diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md
new file mode 100644
index 00000000..dd84ea78
--- /dev/null
+++ b/.github/ISSUE_TEMPLATE/bug_report.md
@@ -0,0 +1,38 @@
+---
+name: Bug report
+about: Create a report to help us improve
+title: ''
+labels: ''
+assignees: ''
+
+---
+
+**Describe the bug**
+A clear and concise description of what the bug is.
+
+**To Reproduce**
+Steps to reproduce the behavior:
+1. Go to '...'
+2. Click on '....'
+3. Scroll down to '....'
+4. See error
+
+**Expected behavior**
+A clear and concise description of what you expected to happen.
+
+**Screenshots**
+If applicable, add screenshots to help explain your problem.
+
+**Desktop (please complete the following information):**
+ - OS: [e.g. iOS]
+ - Browser [e.g. chrome, safari]
+ - Version [e.g. 22]
+
+**Smartphone (please complete the following information):**
+ - Device: [e.g. iPhone6]
+ - OS: [e.g. iOS8.1]
+ - Browser [e.g. stock browser, safari]
+ - Version [e.g. 22]
+
+**Additional context**
+Add any other context about the problem here.
diff --git a/.github/ISSUE_TEMPLATE/feature_request.md b/.github/ISSUE_TEMPLATE/feature_request.md
new file mode 100644
index 00000000..8e8e9472
--- /dev/null
+++ b/.github/ISSUE_TEMPLATE/feature_request.md
@@ -0,0 +1,17 @@
+---
+name: Feature request
+about: Suggest an idea for this project
+title: ''
+labels: enhancement
+assignees: ''
+
+---
+
+**Feature description**
+to be filled by you
+
+**Relevant specifications and corresponding sections**
+to be filled by you
+
+**Additional context**
+to be filled by you
diff --git a/.github/workflows/build-gradle.yml b/.github/workflows/build-gradle.yml
new file mode 100644
index 00000000..34331840
--- /dev/null
+++ b/.github/workflows/build-gradle.yml
@@ -0,0 +1,37 @@
+# This workflow uses actions that are not certified by GitHub.
+# They are provided by a third-party and are governed by
+# separate terms of service, privacy policy, and support
+# documentation.
+# This workflow will build a Java project with Gradle and cache/restore any dependencies to improve the workflow execution time
+# For more information see: https://docs.github.com/en/actions/automating-builds-and-tests/building-and-testing-java-with-gradle
+
+name: Java CI with Gradle
+
+on:
+ pull_request:
+ branches: [ "main", "development" ]
+
+permissions:
+ contents: read
+
+jobs:
+ build:
+ runs-on: ubuntu-latest
+ steps:
+ - uses: actions/checkout@v4
+ with:
+ lfs: 'true'
+ - uses: actions/setup-java@v4
+ with:
+ java-version: '17'
+ distribution: 'temurin'
+ - name: Setup Gradle
+ uses: gradle/actions/setup-gradle@417ae3ccd767c252f5661f1ace9f835f9654f2b5 # v3.1.0
+ - name: Make gradlew executable
+ run: chmod +x ./gradlew
+ - name: Setup cmake
+ uses: jwlawson/actions-setup-cmake@v2
+ with:
+ cmake-version: '3.26.1'
+ - name: Build with Gradle
+ run: ./gradlew build
\ No newline at end of file
diff --git a/.gitignore b/.gitignore
index 547eb34a..e48a6dde 100644
--- a/.gitignore
+++ b/.gitignore
@@ -82,3 +82,5 @@ lint/generated/
lint/outputs/
lint/tmp/
# lint/reports/
+
+.gradle
diff --git a/.idea/compiler.xml b/.idea/compiler.xml
index 7d7ec2ea..8fabff5a 100644
--- a/.idea/compiler.xml
+++ b/.idea/compiler.xml
@@ -1,6 +1,6 @@
-
+
\ No newline at end of file
diff --git a/.idea/misc.xml b/.idea/misc.xml
index d1b2b8d9..5539aa86 100644
--- a/.idea/misc.xml
+++ b/.idea/misc.xml
@@ -1,24 +1,24 @@
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/CONTRIBUTION_NOTICE.md b/CONTRIBUTION_NOTICE.md
new file mode 100644
index 00000000..07f08ef6
--- /dev/null
+++ b/CONTRIBUTION_NOTICE.md
@@ -0,0 +1,2 @@
+# Contribution Notice
+Original development by Klaus Kuenhammer, Bitstem, Nakolos and ORS.
\ No newline at end of file
diff --git a/README.md b/README.md
index 44eee319..2f349d33 100644
--- a/README.md
+++ b/README.md
@@ -1,10 +1,95 @@
-
MBMS Middleware for Android
+
MBMS MW Android
-
-
+
+
## Introduction
-Additional information can be found at: https://5g-mag.github.io/Getting-Started/pages/lte-based-5g-broadcast/
+The MBMS Middleware for Android enables the reception of media content via 5G Broadcast and
+unicast (OTT streaming). Based on an MBMS Service Announcement the media manifests and segments are
+either received directly via 5G Broadcast or fetched via unicast from a CDN. The MBMS Middleware
+exposes the received media files via a local webserver to the MediaPlayer. As a result, the device
+can dynamically switch between broadcast and unicast consumption without the media player being
+aware of how the media files were originally received.
+
+### About the implementation
+
+The implementation is basically a port of
+the [MBMS Middleware](https://github.com/5G-MAG/rt-mbms-mw) to Android. It uses
+the [MbmsGroupCallSession API](https://developer.android.com/reference/android/telephony/MbmsGroupCallSession)
+for accessing packets received via 5G Broadcast.
+
+## Install dependencies
+
+The MBMS MW Android requires Github Large File Storage to be installed before cloning the
+repository. Please check
+the [Github documentation](https://docs.github.com/en/repositories/working-with-files/managing-large-files/installing-git-large-file-storage)
+for details.
+
+## Downloading
+
+Release versions can be downloaded from
+the [releases](https://github.com/5G-MAG/rt-mbms-mw-android/releases) page.
+
+The source can be obtained by cloning the github repository.
+
+```
+cd ~
+git clone https://github.com/5G-MAG/rt-mbms-mw-android
+```
+
+## Building
+
+Call the following command in order to generate the `apk` bundles.
+
+````
+./gradlew assemble
+````
+
+The resulting `apk` bundles can be found in `app/build/outputs/apk`. The debug build is located
+in `debug` folder the release build in the `release` folder.
+
+## Install
+
+To install the `apk` on an Android device follow the following steps:
+
+1. Connect your Android device to your development machine
+2. Call `adb devices` to list the available Android devices. The output should look like the
+ following:
+
+````
+List of devices attached
+CQ30022U4R device
+````
+
+3. Install the `apk` on the target
+ device: `adb -s install -r app/build/outputs/apk/debug/app-debug.apk`. Using `-r`
+ we reinstall an existing app, keeping its data.
+
+## Running
+
+After installing the Media Session Handler application can be started from the Android app selection
+screen.
+
+As an alternative we can also run the app from the command
+line: `adb shell am start -n com.fivegmag.a5gmsmediasessionhandler/com.fivegmag.a5gmsmediasessionhandler.MainActivity `
+
+## Development
+
+This project follows
+the [Gitflow workflow](https://www.atlassian.com/git/tutorials/comparing-workflows/gitflow-workflow)
+. The `development`
+branch of this project serves as an integration branch for new features. Consequently, please make
+sure to switch to the `development`
+branch before starting the implementation of a new feature.
+
+## Acknowledgement
+
+The MBMS MW Android was originally developed by Bistem, Nakolos and ORS.
+
+## Troubleshooting
+
+* If you get an error `gradlew: Permission Denied` try to set the execution flag on your gradlew
+ file: `chmod +x gradlew`
\ No newline at end of file
diff --git a/app/build.gradle b/app/build.gradle
index 5be3fc94..c43109a7 100644
--- a/app/build.gradle
+++ b/app/build.gradle
@@ -11,11 +11,11 @@ android {
compileSdk 33
ndkVersion '25.1.8937393'
defaultConfig {
- applicationId "com.nakolos.ossmw"
+ applicationId "com.fivegmag.ossmw"
minSdk 28
targetSdk 32
versionCode 1
- versionName "0.1.0"
+ versionName "1.0.0"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
externalNativeBuild {
@@ -43,7 +43,7 @@ android {
externalNativeBuild {
cmake {
path file('src/main/cpp/CMakeLists.txt')
- version '3.22.1'
+ version '3.26.1'
}
}
diff --git a/app/src/androidTest/java/com/bitstem/ossmw/ExampleInstrumentedTest.kt b/app/src/androidTest/java/com/bitstem/ossmw/ExampleInstrumentedTest.kt
deleted file mode 100644
index fcf998df..00000000
--- a/app/src/androidTest/java/com/bitstem/ossmw/ExampleInstrumentedTest.kt
+++ /dev/null
@@ -1,24 +0,0 @@
-package com.bitstem.`nakolos-mw`
-
-import androidx.test.platform.app.InstrumentationRegistry
-import androidx.test.ext.junit.runners.AndroidJUnit4
-
-import org.junit.Test
-import org.junit.runner.RunWith
-
-import org.junit.Assert.*
-
-/**
- * Instrumented test, which will execute on an Android device.
- *
- * See [testing documentation](http://d.android.com/tools/testing).
- */
-@RunWith(AndroidJUnit4::class)
-class ExampleInstrumentedTest {
- @Test
- fun useAppContext() {
- // Context of the app under test.
- val appContext = InstrumentationRegistry.getInstrumentation().targetContext
- assertEquals("com.bitstem.libflute", appContext.packageName)
- }
-}
\ No newline at end of file
diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index 10344a5d..998e6339 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -1,7 +1,7 @@
+ package="com.fivegmag.ossmw">
@@ -18,20 +18,20 @@
android:theme="@style/Theme.LibFlute"
tools:targetApi="31">
@@ -39,7 +39,7 @@
diff --git a/app/src/main/assets/bootstrap.multipart.hls b/app/src/main/assets/bootstrap.multipart.hls
new file mode 100644
index 00000000..b3b60ffd
--- /dev/null
+++ b/app/src/main/assets/bootstrap.multipart.hls
@@ -0,0 +1,158 @@
+--++++++++++++++++++++++++Rohde&Schwarz-BSCC++++++++++++++++++++++++--
+Content-Type: application/mbms-envelope+xml
+Content-Transfer-Encoding: 7bit
+Content-Location: file:///envelope.xml
+
+
+
+
+
+
+
+
+
+--++++++++++++++++++++++++Rohde&Schwarz-BSCC++++++++++++++++++++++++--
+Content-Type: application/sdp
+Content-Transfer-Encoding: 7bit
+Content-Location: file:///TMGI-0x1009f165.sdp
+
+v=0
+o=ROHDE-SCHWARZ-BSCC 269087077 1634036383 IN IP4 11.11.11.11
+s=HLS Streaming Session 0x1009f165
+i=File Download Session
+t=3843025183 4789105183
+a=mbms-mode:broadcast-mbsfn 269087077
+c=IN IP4 239.11.4.9/127
+b=AS:2000
+m=application 5519 FLUTE/UDP 0
+a=flute-tsi:0
+a=flute-ch:1
+a=3GPP-QoE-Metrics:metrics={Object_Loss};rate=null;resolution=10
+a=3GPP-QoE-Metrics:metrics={Network_Resource};rate=null;resolution=10
+
+--++++++++++++++++++++++++Rohde&Schwarz-BSCC++++++++++++++++++++++++--
+Content-Type: application/vnd.apple.mpegurl
+Content-Transfer-Encoding: 7bit
+Content-Location: file:///TMGI-0x1009f165.m3u8
+
+#EXTM3U
+#EXT-X-VERSION:3
+
+#EXT-X-STREAM-INF:CODECS="avc1.4D401E,mp4a.40.2",BANDWIDTH=1425427,FRAME-RATE=25.000,RESOLUTION=640x360
+watchfolder/hls/stream_0.m3u8
+
+--++++++++++++++++++++++++Rohde&Schwarz-BSCC++++++++++++++++++++++++--
+Content-Type: application/vnd.apple.mpegurl
+Content-Transfer-Encoding: 7bit
+Content-Location: http://192.168.2.2:3333/watchfolder/hls/manifest.m3u8
+
+#EXTM3U
+#EXT-X-VERSION:3
+#EXT-X-STREAM-INF:BANDWIDTH=3845427,AVERAGE-BANDWIDTH=3845427,RESOLUTION=1280x720,FRAME-RATE=25.000,CODECS="avc1.64001F,mp4a.40.2"
+watchfolder/hls/stream_0.m3u8
+
+--++++++++++++++++++++++++Rohde&Schwarz-BSCC++++++++++++++++++++++++--
+Content-Type: application/mbms-user-service-description+xml
+Content-Transfer-Encoding: 7bit
+Content-Location: file:///usdBundle.xml
+
+
+
+ 1
+
+ BSCC Service1
+ BSCC Dienst1
+ EN-GB
+ DE-DE
+
+ 23
+ 27
+
+
+ 0
+
+ file:///TMGI-0x1009f165.m3u8
+ 2
+
+
+ http://192.168.2.2:3333/watchfolder/hls/manifest.m3u8
+
+ 0
+
+
+
+ file:///TMGI-0x1009f165.m3u8
+
+
+ file:///TMGI-0x1009f165.m3u8
+ http://192.168.2.2:3333/watchfolder/hls/stream_0.m3u8
+
+
+
+ file:///TMGI-0x1009f165schedule.xml
+
+ 0
+
+
+ 2
+
+
+
+
+--++++++++++++++++++++++++Rohde&Schwarz-BSCC++++++++++++++++++++++++--
+Content-Type: application/mbms-schedule+xml
+Content-Transfer-Encoding: 7bit
+Content-Location: file:///TMGI-0x1009f165schedule.xml
+
+
+
+ 1
+
+
+ 2021-10-12T10:59:43Z
+ 2051-10-05T10:59:43Z
+ 0
+ 0
+ 0
+
+
+
+--++++++++++++++++++++++++Rohde&Schwarz-BSCC++++++++++++++++++++++++--
diff --git a/app/src/main/cpp/HlsMediaPlaylist.cpp b/app/src/main/cpp/HlsMediaPlaylist.cpp
index 0048ff14..fdf23758 100644
--- a/app/src/main/cpp/HlsMediaPlaylist.cpp
+++ b/app/src/main/cpp/HlsMediaPlaylist.cpp
@@ -21,70 +21,82 @@
#include "boost/algorithm/string.hpp"
#include
-MBMS_RT::HlsMediaPlaylist::HlsMediaPlaylist(const std::string& content)
-{
- spdlog::debug("Parsing HLS media playlist: {}", content);
+MBMS_RT::HlsMediaPlaylist::HlsMediaPlaylist(const std::string &content) {
+ spdlog::debug("Parsing HLS media playlist: {}", content);
- std::istringstream iss(content);
- int idx = 0;
- int seq_nr = 0;
- double extinf = -1;
- for (std::string line; std::getline(iss, line); idx++ )
- {
- boost::algorithm::trim(line);
+ std::istringstream iss(content);
+ int idx = 0;
+ int seq_nr = 0;
+ double extinf = -1;
+ for (std::string line; std::getline(iss, line); idx++) {
+ boost::algorithm::trim(line);
- if (idx==0) {
- if ( line != "#EXTM3U") {
- throw("HLS playlist parsing failed: first line is not #EXTM3U");
- } else {
- continue;
- }
- }
+ if (idx == 0) {
+ if (line != "#EXTM3U") {
+ throw ("HLS playlist parsing failed: first line is not #EXTM3U");
+ } else {
+ continue;
+ }
+ }
- size_t cpos = line.rfind(':');
+ size_t cpos = line.rfind(':');
- if (line.rfind("#EXT-X-VERSION", 0) == 0) {
- if (_version != -1) {
- throw("HLS playlist parsing failed: duplicate #EXT-X-VERSION");
- }
- if (cpos != std::string::npos) {
- _version = atoi(line.substr(cpos+1).c_str());
- }
- } else if (line.rfind("#EXT-X-TARGETDURATION", 0) == 0) {
- if (cpos != std::string::npos) {
- _targetduration = atoi(line.substr(cpos+1).c_str());
- }
- } else if (line.rfind("#EXT-X-MEDIA-SEQUENCE", 0) == 0) {
- if (cpos != std::string::npos) {
- seq_nr = atoi(line.substr(cpos+1).c_str());
- }
- } else if (line.rfind("#EXTINF", 0) == 0) {
- if (cpos != std::string::npos) {
- extinf = atof(line.substr(cpos+1).c_str());
- }
- } else if (line.rfind('#', 0) == 0) {
- spdlog::debug("HLS playlist parser ignoring unhandled line {}", line);
- } else if (line.size() > 0) {
- _segments.push_back({line, seq_nr++, extinf});
+ if (line.rfind("#EXT-X-VERSION", 0) == 0) {
+ if (_version != -1) {
+ throw ("HLS playlist parsing failed: duplicate #EXT-X-VERSION");
+ }
+ if (cpos != std::string::npos) {
+ _version = atoi(line.substr(cpos + 1).c_str());
+ }
+ } else if (line.rfind("#EXT-X-TARGETDURATION", 0) == 0) {
+ if (cpos != std::string::npos) {
+ _targetduration = atoi(line.substr(cpos + 1).c_str());
+ }
+ } else if (line.rfind("#EXT-X-MEDIA-SEQUENCE", 0) == 0) {
+ if (cpos != std::string::npos) {
+ seq_nr = atoi(line.substr(cpos + 1).c_str());
+ }
+ } else if (line.rfind("#EXTINF", 0) == 0) {
+ if (cpos != std::string::npos) {
+ extinf = atof(line.substr(cpos + 1).c_str());
+ }
+ } else if (line.rfind('#', 0) == 0) {
+ spdlog::debug("HLS playlist parser ignoring unhandled line {}", line);
+ } else if (line.size() > 0) {
+ _segments.push_back({line, seq_nr++, extinf});
+ }
}
- }
}
-auto MBMS_RT::HlsMediaPlaylist::to_string() const -> std::string
-{
- std::stringstream pl;
+auto MBMS_RT::HlsMediaPlaylist::to_string() const -> std::string {
+ std::stringstream pl;
- pl << "#EXTM3U" << std::endl;
- pl << "#EXT-X-VERSION:3" << std::endl;
+ pl << "#EXTM3U" << std::endl;
+ pl << "#EXT-X-VERSION:3" << std::endl;
- if (_segments.size() > 0) {
- pl << "#EXT-X-TARGETDURATION:" << _targetduration << std::endl;
- pl << "#EXT-X-MEDIA-SEQUENCE:" << _segments[0].seq << std::endl;
- }
- for (const auto& seg : _segments) {
- pl << "#EXTINF:" << seg.extinf << std::endl;
- pl << "/" << seg.uri << std::endl;
- }
- return std::move(pl.str());
+ if (_segments.size() > 0) {
+ pl << "#EXT-X-TARGETDURATION:" << _targetduration << std::endl;
+ pl << "#EXT-X-MEDIA-SEQUENCE:" << _segments[0].seq << std::endl;
+ }
+ for (const auto &seg: _segments) {
+ pl << "#EXTINF:" << seg.extinf << std::endl;
+ pl << "" << remove_base_url(seg.uri) << std::endl;
+ //pl << "/" << seg.uri << std::endl;
+ }
+ return std::move(pl.str());
}
+
+auto MBMS_RT::HlsMediaPlaylist::remove_base_url(std::string uri) const -> std::string {
+ size_t lastSlashPos = uri.find_last_of('/');
+
+ // Extract the substring after the last slash
+ if (lastSlashPos != std::string::npos) {
+ std::string lastPart = uri.substr(lastSlashPos + 1);
+ return lastPart;
+ } else {
+ return uri;
+ }
+
+}
+
diff --git a/app/src/main/cpp/HlsMediaPlaylist.h b/app/src/main/cpp/HlsMediaPlaylist.h
index 158a3de8..9fb642e9 100644
--- a/app/src/main/cpp/HlsMediaPlaylist.h
+++ b/app/src/main/cpp/HlsMediaPlaylist.h
@@ -36,6 +36,7 @@ namespace MBMS_RT {
void add_segment(Segment segment) { _segments.push_back(std::move(segment)); };
std::string to_string() const;
+ std::string remove_base_url(std::string uri) const;
void set_target_duration(int duration) { _targetduration = duration; };
int target_duration() const { return _targetduration; };
diff --git a/app/src/main/cpp/RestHandler.cpp b/app/src/main/cpp/RestHandler.cpp
index 08938e23..f188fbc6 100644
--- a/app/src/main/cpp/RestHandler.cpp
+++ b/app/src/main/cpp/RestHandler.cpp
@@ -228,7 +228,7 @@ void MBMS_RT::RestHandler::get(http_request message) {
if (it->second->buffer() != nullptr) {
web::http::http_response response(status_codes::OK);
if (it->second->item_type() == CacheItem::ItemType::Segment) {
- response.headers().add(U("NAKOLOS-File-Origin"), it->second->item_source_as_string());
+ response.headers().add(U("FIVEGMAG-File-Origin"), it->second->item_source_as_string());
if (_active_source_cb) _active_source_cb(it->second->item_source_as_string());
} else {
if (_active_stream_cb) _active_stream_cb(it->second->content_location());
diff --git a/app/src/main/cpp/android-jni-bindings.cpp b/app/src/main/cpp/android-jni-bindings.cpp
index 8d71e2ec..f93c978d 100644
--- a/app/src/main/cpp/android-jni-bindings.cpp
+++ b/app/src/main/cpp/android-jni-bindings.cpp
@@ -29,13 +29,13 @@ extern "C" jint JNI_OnLoad(JavaVM* vm, void* reserved)
}
extern "C" JNIEXPORT bool JNICALL
-Java_com_nakolos_ossmw_NakolosMwService_startNativeMiddleware(JNIEnv* env,
-jobject thiz, jstring device_name, jstring japi_key) {
- std::string tag = "nakolos-mw";
+Java_com_fivegmag_ossmw_MwService_startNativeMiddleware(JNIEnv* env,
+ jobject thiz, jstring device_name, jstring japi_key) {
+ std::string tag = "fivegmag-mw";
try {
- auto android_logger = spdlog::android_logger_mt("nakolos-mw", tag);
+ auto android_logger = spdlog::android_logger_mt("fivegmag-mw", tag);
spdlog::set_default_logger(android_logger);
- spdlog::info("Launching NAKOLOS native middleware");
+ spdlog::info("Launching 5G-MAG native middleware");
spdlog::set_level(spdlog::level::debug);
} catch (...) {}
@@ -60,7 +60,7 @@ jobject thiz, jstring device_name, jstring japi_key) {
}
extern "C" JNIEXPORT bool JNICALL
-Java_com_nakolos_ossmw_UdpReceiver_handlePacket(JNIEnv* env,
+Java_com_fivegmag_ossmw_UdpReceiver_handlePacket(JNIEnv* env,
jobject thiz,
jbyteArray buffer,
jint size) {
@@ -73,9 +73,9 @@ Java_com_nakolos_ossmw_UdpReceiver_handlePacket(JNIEnv* env,
return true;
}
extern "C" JNIEXPORT bool JNICALL
-Java_com_nakolos_ossmw_NakolosMwService_setLocalServiceAnnouncement(JNIEnv* env,
- jobject thiz,
- jstring sa) {
+Java_com_fivegmag_ossmw_MwService_setLocalServiceAnnouncement(JNIEnv* env,
+ jobject thiz,
+ jstring sa) {
const char *csa = env->GetStringUTFChars(sa, NULL);
mw->set_local_service_announcement(csa);
env->ReleaseStringUTFChars(sa,csa);
@@ -83,8 +83,8 @@ Java_com_nakolos_ossmw_NakolosMwService_setLocalServiceAnnouncement(JNIEnv* env,
}
extern "C" JNIEXPORT bool JNICALL
-Java_com_nakolos_ossmw_NakolosMwService_stopNativeMiddleware(JNIEnv* env,
- jobject thiz) {
+Java_com_fivegmag_ossmw_MwService_stopNativeMiddleware(JNIEnv* env,
+ jobject thiz) {
using namespace std::chrono_literals;
spdlog::info("Stopping io_service tasks");
if (mw) {
diff --git a/app/src/main/cpp/libflute/Receiver.cpp b/app/src/main/cpp/libflute/Receiver.cpp
index 1df6cb47..28a384a8 100644
--- a/app/src/main/cpp/libflute/Receiver.cpp
+++ b/app/src/main/cpp/libflute/Receiver.cpp
@@ -253,7 +253,7 @@ auto LibFlute::Receiver::remove_expired_files(unsigned max_age) -> void
for (auto it = _files.cbegin(); it != _files.cend();)
{
auto age = time(nullptr) - it->second->received_at();
- if ( it->second->meta().content_location != "bootstrap.multipart" && age > max_age) {
+ if ( it->second->meta().content_location != "bootstrap.multipart.hls" && age > max_age) {
it = _files.erase(it);
} else {
++it;
diff --git a/app/src/main/cpp/seamless/CdnClient.cpp b/app/src/main/cpp/seamless/CdnClient.cpp
index d09dedb2..8ecf1131 100644
--- a/app/src/main/cpp/seamless/CdnClient.cpp
+++ b/app/src/main/cpp/seamless/CdnClient.cpp
@@ -58,7 +58,7 @@ auto MBMS_RT::CdnClient::get(const std::string& path, std::function req{http::verb::get, _base_path + path, 11};
req.set(http::field::host, _host);
- req.set(http::field::user_agent, "nakolos MW/0.9");
+ req.set(http::field::user_agent, "fivegmag MW/0.9");
http::write(stream, req);
beast::flat_buffer buffer(1024*1024*128);
diff --git a/app/src/main/cpp/seamless/SeamlessContentStream.cpp b/app/src/main/cpp/seamless/SeamlessContentStream.cpp
index 00a05f3e..d93990a4 100644
--- a/app/src/main/cpp/seamless/SeamlessContentStream.cpp
+++ b/app/src/main/cpp/seamless/SeamlessContentStream.cpp
@@ -77,8 +77,8 @@ auto MBMS_RT::SeamlessContentStream::set_cdn_endpoint(const std::string& cdn_ept
size_t spos = _playlist_path.rfind('/');
_playlist_dir = _playlist_path.substr(0, spos+1);
spdlog::debug("ContentStream: playlist dir is {}", _playlist_dir);
- //cdn_base.set_path("/");
- cdn_base.set_path("/cdn/");
+ cdn_base.set_path("/");
+ //cdn_base.set_path("/cdn/");
cdn_base.set_query("");
_cdn_endpoint = cdn_base.to_string();
spdlog::info("ContentStream: setting CDN ept to {}", _cdn_endpoint);
@@ -121,7 +121,7 @@ auto MBMS_RT::SeamlessContentStream::handle_playlist( const std::string& content
for (const auto& segment : playlist.segments()) {
// spdlog::debug("segment: seq {}, extinf {}, uri {}", segment.seq, segment.extinf, segment.uri);
if (_segments[plidx].find(segment.seq) == _segments[plidx].end()) {
- std::string full_uri = (plidx == 0 ? "ch1/" : "ch2/") + segment.uri;
+ std::string full_uri = (plidx == 0 ? "watchfolder/hls/" : "ch2/") + segment.uri;
auto seg =
std::make_shared(full_uri, segment.seq, segment.extinf);
if (_cdn_client) {
diff --git a/app/src/main/ic_launcher-playstore.png b/app/src/main/ic_launcher-playstore.png
new file mode 100644
index 00000000..ffb6406c
Binary files /dev/null and b/app/src/main/ic_launcher-playstore.png differ
diff --git a/app/src/main/java/com/nakolos/ossmw/Actions.kt b/app/src/main/java/com/fivegmag/ossmw/Actions.kt
similarity index 94%
rename from app/src/main/java/com/nakolos/ossmw/Actions.kt
rename to app/src/main/java/com/fivegmag/ossmw/Actions.kt
index a1ba7fa7..a9346212 100644
--- a/app/src/main/java/com/nakolos/ossmw/Actions.kt
+++ b/app/src/main/java/com/fivegmag/ossmw/Actions.kt
@@ -1,21 +1,21 @@
-// Copyright (C) 2023 Klaus Kühnhammer (Österreichische Rundfunksender GmbH & Co KG)
-//
-// 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.
-//
-// 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 .
-
-package com.nakolos.ossmw
-
-enum class Actions {
- START,
- STOP
+// Copyright (C) 2023 Klaus Kühnhammer (Österreichische Rundfunksender GmbH & Co KG)
+//
+// 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.
+//
+// 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 .
+
+package com.fivegmag.ossmw
+
+enum class Actions {
+ START,
+ STOP
}
\ No newline at end of file
diff --git a/app/src/main/java/com/nakolos/ossmw/CppOssNoticesActivity.kt b/app/src/main/java/com/fivegmag/ossmw/CppOssNoticesActivity.kt
similarity index 97%
rename from app/src/main/java/com/nakolos/ossmw/CppOssNoticesActivity.kt
rename to app/src/main/java/com/fivegmag/ossmw/CppOssNoticesActivity.kt
index 200a759d..87f5e1eb 100644
--- a/app/src/main/java/com/nakolos/ossmw/CppOssNoticesActivity.kt
+++ b/app/src/main/java/com/fivegmag/ossmw/CppOssNoticesActivity.kt
@@ -13,7 +13,7 @@
// You should have received a copy of the GNU Affero General Public License
// along with this program. If not, see .
-package com.nakolos.ossmw
+package com.fivegmag.ossmw
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
diff --git a/app/src/main/java/com/nakolos/ossmw/LicenseActivity.kt b/app/src/main/java/com/fivegmag/ossmw/LicenseActivity.kt
similarity index 94%
rename from app/src/main/java/com/nakolos/ossmw/LicenseActivity.kt
rename to app/src/main/java/com/fivegmag/ossmw/LicenseActivity.kt
index 1281abd5..92acff96 100644
--- a/app/src/main/java/com/nakolos/ossmw/LicenseActivity.kt
+++ b/app/src/main/java/com/fivegmag/ossmw/LicenseActivity.kt
@@ -13,12 +13,12 @@
// You should have received a copy of the GNU Affero General Public License
// along with this program. If not, see .
-package com.nakolos.ossmw
+package com.fivegmag.ossmw
import android.os.Bundle
import android.widget.TextView
import androidx.appcompat.app.AppCompatActivity
-import com.nakolos.ossmw.databinding.ActivityLicenseBinding
+import com.fivegmag.ossmw.databinding.ActivityLicenseBinding
class LicenseActivity : AppCompatActivity() {
diff --git a/app/src/main/java/com/nakolos/ossmw/MainActivity.kt b/app/src/main/java/com/fivegmag/ossmw/MainActivity.kt
similarity index 95%
rename from app/src/main/java/com/nakolos/ossmw/MainActivity.kt
rename to app/src/main/java/com/fivegmag/ossmw/MainActivity.kt
index c62b6ff7..9c7ea8a3 100644
--- a/app/src/main/java/com/nakolos/ossmw/MainActivity.kt
+++ b/app/src/main/java/com/fivegmag/ossmw/MainActivity.kt
@@ -13,14 +13,13 @@
// You should have received a copy of the GNU Affero General Public License
// along with this program. If not, see .
-package com.nakolos.ossmw
+package com.fivegmag.ossmw
import android.content.Intent
import android.os.Build
import android.os.Bundle
import android.os.Handler
import android.os.Looper
-import android.util.Log
import android.widget.Button
import android.widget.TextView
import androidx.appcompat.app.AppCompatActivity
@@ -36,8 +35,7 @@ import androidx.media3.exoplayer.source.*
import androidx.media3.exoplayer.upstream.DefaultLoadErrorHandlingPolicy
import androidx.media3.exoplayer.upstream.LoadErrorHandlingPolicy
import androidx.media3.ui.PlayerView
-import com.nakolos.ossmw.databinding.ActivityMainBinding
-import java.net.InetAddress
+import com.fivegmag.ossmw.databinding.ActivityMainBinding
class RetryOnErrorPolicy : DefaultLoadErrorHandlingPolicy() {
override fun getRetryDelayMsFor(loadErrorInfo: LoadErrorHandlingPolicy.LoadErrorInfo): Long {
@@ -92,7 +90,7 @@ class MainActivity : AppCompatActivity() {
}
private fun actionOnService(action: Actions) {
// if (getServiceState(this) == ServiceState.STOPPED && action == Actions.STOP) return
- Intent(this, NakolosMwService::class.java).also {
+ Intent(this, MwService::class.java).also {
it.action = action.name
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
// log("Starting the service in >=26 Mode")
@@ -120,8 +118,8 @@ class MainActivity : AppCompatActivity() {
val cdn_ept = "http://127.0.0.1:" +
3020 + "/" +
- "ch1" + "/" +
- "stream.m3u8"
+ "watchfolder/hls" + "/" +
+ "stream_0.m3u8"
val mediaSource: MediaSource =
HlsMediaSource.Factory(dataSourceFactory)
.setLoadErrorHandlingPolicy(policy)
@@ -136,8 +134,8 @@ class MainActivity : AppCompatActivity() {
loadEventInfo: LoadEventInfo,
mediaLoadData: MediaLoadData
) {
- if (loadEventInfo.responseHeaders.contains("NAKOLOS-File-Origin")) {
- for (header in loadEventInfo.responseHeaders.get("NAKOLOS-File-Origin")!!) {
+ if (loadEventInfo.responseHeaders.contains("FIVEGMAG-File-Origin")) {
+ for (header in loadEventInfo.responseHeaders.get("FIVEGMAG-File-Origin")!!) {
sourceInfoText.text = header;
if (lastSource != header) {
lastSource = header
diff --git a/app/src/main/java/com/nakolos/ossmw/NakolosMwService.kt b/app/src/main/java/com/fivegmag/ossmw/MwService.kt
similarity index 94%
rename from app/src/main/java/com/nakolos/ossmw/NakolosMwService.kt
rename to app/src/main/java/com/fivegmag/ossmw/MwService.kt
index df355ed5..1103aabb 100644
--- a/app/src/main/java/com/nakolos/ossmw/NakolosMwService.kt
+++ b/app/src/main/java/com/fivegmag/ossmw/MwService.kt
@@ -13,7 +13,7 @@
// You should have received a copy of the GNU Affero General Public License
// along with this program. If not, see .
-package com.nakolos.ossmw
+package com.fivegmag.ossmw
import android.annotation.SuppressLint
import android.app.*
@@ -39,9 +39,9 @@ import java.util.concurrent.ExecutorService
import java.util.concurrent.Executors
-private const val TAG = "NakolosMW"
+private const val TAG = "5G-MAG MW"
-class NakolosMwService : Service() {
+class MwService : Service() {
private var groupCallSession: MbmsGroupCallSession? = null
private lateinit var groupCallSessionCallback: MbmsGroupCallSessionCallback
@@ -56,7 +56,7 @@ class NakolosMwService : Service() {
private var isServiceStarted = false
fun log(msg: String) {
- Log.d("NAKOLOS MW Service", msg)
+ Log.d("5G-MAG MW Service", msg)
}
@@ -199,8 +199,8 @@ class NakolosMwService : Service() {
@RequiresApi(Build.VERSION_CODES.Q)
private fun startService() {
if (isServiceStarted) return
- log("Starting the NAKOLOS MW foreground service task")
- Toast.makeText(this, "NAKOLOS MW started", Toast.LENGTH_SHORT).show()
+ log("Starting the FIVEGMAG MW foreground service task")
+ Toast.makeText(this, "5G-MAG MW started", Toast.LENGTH_SHORT).show()
isServiceStarted = true
wakeLock =
@@ -227,7 +227,7 @@ class NakolosMwService : Service() {
startNativeMiddleware(userDeviceName, api_key!!)
- var service_announcement = readAssetFile("bootstrap.multipart")
+ var service_announcement = readAssetFile("bootstrap.multipart.hls")
//var service_announcement = readAssetFile("bootstrap.multipart.debug")
if (service_announcement != null) {
setLocalServiceAnnouncement(service_announcement)
@@ -252,13 +252,13 @@ class NakolosMwService : Service() {
udpReceiver.running = false
stopNativeMiddleware()
disconnectFromMiddleware()
- Toast.makeText(this, "NAKOLOS MW stopped", Toast.LENGTH_SHORT).show()
+ Toast.makeText(this, "5G-MAG MW stopped", Toast.LENGTH_SHORT).show()
}
// override fun onBind(intent: Intent): IBinder? {
// return null
// }
private fun createNotification(): Notification {
- val notificationChannelId = "NAKOLOS MW"
+ val notificationChannelId = "FIVEGMAG MW"
// depending on the Android API that we're dealing with we will have
// to use a specific method to create the notification
@@ -267,10 +267,10 @@ class NakolosMwService : Service() {
val notificationManager = getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager;
val channel = NotificationChannel(
notificationChannelId,
- "NAKOLOS middleware notifications channel",
+ "5G-MAG middleware notifications channel",
NotificationManager.IMPORTANCE_HIGH
).let {
- it.description = "NAKOLOS middleware notifications channel"
+ it.description = "5G-MAG middleware notifications channel"
it.enableLights(true)
it.lightColor = Color.RED
it.enableVibration(false)
@@ -290,8 +290,8 @@ class NakolosMwService : Service() {
) else Notification.Builder(this)
return builder
- .setContentTitle("NAKOLOS")
- .setContentText("NAKOLOS middleware is running")
+ .setContentTitle("5G-MAG")
+ .setContentText("5G-MAG middleware is running")
.setContentIntent(pendingIntent)
.setSmallIcon(R.drawable.ic_stat_name)
.setTicker("Ticker text")
@@ -326,8 +326,8 @@ class UdpReceiver(applicationContext: Context, interfaceName: String) : Runnable
var running = true
public override fun run() {
- address = InetAddress.getByName("239.11.4.10")
- socketAddress = InetSocketAddress(address, 5501)
+ address = InetAddress.getByName("239.11.4.50")
+ socketAddress = InetSocketAddress(address, 9988)
multicastSocket = MulticastSocket(socketAddress)
multicastSocket!!.networkInterface = NetworkInterface.getByName(interfaceName)
diff --git a/app/src/main/java/com/nakolos/ossmw/SettingsActivity.kt b/app/src/main/java/com/fivegmag/ossmw/SettingsActivity.kt
similarity index 98%
rename from app/src/main/java/com/nakolos/ossmw/SettingsActivity.kt
rename to app/src/main/java/com/fivegmag/ossmw/SettingsActivity.kt
index e1305b07..c47323ba 100644
--- a/app/src/main/java/com/nakolos/ossmw/SettingsActivity.kt
+++ b/app/src/main/java/com/fivegmag/ossmw/SettingsActivity.kt
@@ -13,7 +13,7 @@
// You should have received a copy of the GNU Affero General Public License
// along with this program. If not, see .
-package com.nakolos.ossmw
+package com.fivegmag.ossmw
import android.content.Intent
import android.os.Bundle
diff --git a/app/src/main/res/drawable/ic_launcher_background.xml b/app/src/main/res/drawable/ic_launcher_background.xml
deleted file mode 100644
index 07d5da9c..00000000
--- a/app/src/main/res/drawable/ic_launcher_background.xml
+++ /dev/null
@@ -1,170 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/app/src/main/res/layout/activity_main.xml b/app/src/main/res/layout/activity_main.xml
index c302fb24..cc7e3e34 100644
--- a/app/src/main/res/layout/activity_main.xml
+++ b/app/src/main/res/layout/activity_main.xml
@@ -10,18 +10,18 @@
+ android:paddingRight="20dp">
+ android:paddingTop="50dp"
+ android:paddingBottom="30dp"
+ android:src="@drawable/fiveg_mag">
+
+
+
+ android:layout_marginTop="20dp"
+ android:text="Start Middleware"
+ android:backgroundTint="@color/fivegmag_blue"
+ android:textColor="@color/white"/>
+ android:text="Stop Middleware"
+ android:backgroundTint="@color/fivegmag_blue"
+ android:textColor="@color/white"/>
+ android:text="Settings & Info"
+ android:backgroundTint="@color/fivegmag_blue"
+ android:textColor="@color/white"/>
diff --git a/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml b/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml
index 90f95809..036d09bc 100644
--- a/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml
+++ b/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml
@@ -1,5 +1,5 @@
-
-
+
+
\ No newline at end of file
diff --git a/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml b/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml
new file mode 100644
index 00000000..036d09bc
--- /dev/null
+++ b/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/mipmap-hdpi/ic_launcher.png b/app/src/main/res/mipmap-hdpi/ic_launcher.png
index 7fc2f2a1..496a010d 100644
Binary files a/app/src/main/res/mipmap-hdpi/ic_launcher.png and b/app/src/main/res/mipmap-hdpi/ic_launcher.png differ
diff --git a/app/src/main/res/mipmap-hdpi/ic_launcher_adaptive_back.png b/app/src/main/res/mipmap-hdpi/ic_launcher_adaptive_back.png
deleted file mode 100644
index 6bb54042..00000000
Binary files a/app/src/main/res/mipmap-hdpi/ic_launcher_adaptive_back.png and /dev/null differ
diff --git a/app/src/main/res/mipmap-hdpi/ic_launcher_adaptive_fore.png b/app/src/main/res/mipmap-hdpi/ic_launcher_adaptive_fore.png
deleted file mode 100644
index b5f8a78d..00000000
Binary files a/app/src/main/res/mipmap-hdpi/ic_launcher_adaptive_fore.png and /dev/null differ
diff --git a/app/src/main/res/mipmap-hdpi/ic_launcher_foreground.png b/app/src/main/res/mipmap-hdpi/ic_launcher_foreground.png
new file mode 100644
index 00000000..81e0f743
Binary files /dev/null and b/app/src/main/res/mipmap-hdpi/ic_launcher_foreground.png differ
diff --git a/app/src/main/res/mipmap-hdpi/ic_launcher_round.png b/app/src/main/res/mipmap-hdpi/ic_launcher_round.png
new file mode 100644
index 00000000..2ebed186
Binary files /dev/null and b/app/src/main/res/mipmap-hdpi/ic_launcher_round.png differ
diff --git a/app/src/main/res/mipmap-mdpi/ic_launcher.png b/app/src/main/res/mipmap-mdpi/ic_launcher.png
index c9864700..0df86ae5 100644
Binary files a/app/src/main/res/mipmap-mdpi/ic_launcher.png and b/app/src/main/res/mipmap-mdpi/ic_launcher.png differ
diff --git a/app/src/main/res/mipmap-mdpi/ic_launcher_adaptive_back.png b/app/src/main/res/mipmap-mdpi/ic_launcher_adaptive_back.png
deleted file mode 100644
index 59c9cafc..00000000
Binary files a/app/src/main/res/mipmap-mdpi/ic_launcher_adaptive_back.png and /dev/null differ
diff --git a/app/src/main/res/mipmap-mdpi/ic_launcher_adaptive_fore.png b/app/src/main/res/mipmap-mdpi/ic_launcher_adaptive_fore.png
deleted file mode 100644
index d044621e..00000000
Binary files a/app/src/main/res/mipmap-mdpi/ic_launcher_adaptive_fore.png and /dev/null differ
diff --git a/app/src/main/res/mipmap-mdpi/ic_launcher_foreground.png b/app/src/main/res/mipmap-mdpi/ic_launcher_foreground.png
new file mode 100644
index 00000000..68e10b89
Binary files /dev/null and b/app/src/main/res/mipmap-mdpi/ic_launcher_foreground.png differ
diff --git a/app/src/main/res/mipmap-mdpi/ic_launcher_round.png b/app/src/main/res/mipmap-mdpi/ic_launcher_round.png
new file mode 100644
index 00000000..d58cc01a
Binary files /dev/null and b/app/src/main/res/mipmap-mdpi/ic_launcher_round.png differ
diff --git a/app/src/main/res/mipmap-xhdpi/ic_launcher.png b/app/src/main/res/mipmap-xhdpi/ic_launcher.png
index 9484ae9b..196f0a85 100644
Binary files a/app/src/main/res/mipmap-xhdpi/ic_launcher.png and b/app/src/main/res/mipmap-xhdpi/ic_launcher.png differ
diff --git a/app/src/main/res/mipmap-xhdpi/ic_launcher_adaptive_back.png b/app/src/main/res/mipmap-xhdpi/ic_launcher_adaptive_back.png
deleted file mode 100644
index c937675a..00000000
Binary files a/app/src/main/res/mipmap-xhdpi/ic_launcher_adaptive_back.png and /dev/null differ
diff --git a/app/src/main/res/mipmap-xhdpi/ic_launcher_adaptive_fore.png b/app/src/main/res/mipmap-xhdpi/ic_launcher_adaptive_fore.png
deleted file mode 100644
index f0a6ed4b..00000000
Binary files a/app/src/main/res/mipmap-xhdpi/ic_launcher_adaptive_fore.png and /dev/null differ
diff --git a/app/src/main/res/mipmap-xhdpi/ic_launcher_foreground.png b/app/src/main/res/mipmap-xhdpi/ic_launcher_foreground.png
new file mode 100644
index 00000000..82e81646
Binary files /dev/null and b/app/src/main/res/mipmap-xhdpi/ic_launcher_foreground.png differ
diff --git a/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png b/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png
new file mode 100644
index 00000000..3a111aa6
Binary files /dev/null and b/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png differ
diff --git a/app/src/main/res/mipmap-xxhdpi/ic_launcher.png b/app/src/main/res/mipmap-xxhdpi/ic_launcher.png
index 04372464..3434d4dc 100644
Binary files a/app/src/main/res/mipmap-xxhdpi/ic_launcher.png and b/app/src/main/res/mipmap-xxhdpi/ic_launcher.png differ
diff --git a/app/src/main/res/mipmap-xxhdpi/ic_launcher_adaptive_back.png b/app/src/main/res/mipmap-xxhdpi/ic_launcher_adaptive_back.png
deleted file mode 100644
index 690a1e58..00000000
Binary files a/app/src/main/res/mipmap-xxhdpi/ic_launcher_adaptive_back.png and /dev/null differ
diff --git a/app/src/main/res/mipmap-xxhdpi/ic_launcher_adaptive_fore.png b/app/src/main/res/mipmap-xxhdpi/ic_launcher_adaptive_fore.png
deleted file mode 100644
index db5607ff..00000000
Binary files a/app/src/main/res/mipmap-xxhdpi/ic_launcher_adaptive_fore.png and /dev/null differ
diff --git a/app/src/main/res/mipmap-xxhdpi/ic_launcher_foreground.png b/app/src/main/res/mipmap-xxhdpi/ic_launcher_foreground.png
new file mode 100644
index 00000000..992b4d41
Binary files /dev/null and b/app/src/main/res/mipmap-xxhdpi/ic_launcher_foreground.png differ
diff --git a/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png b/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png
new file mode 100644
index 00000000..278c9712
Binary files /dev/null and b/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png differ
diff --git a/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png b/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png
index 45296e2b..40d6d6e6 100644
Binary files a/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png and b/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png differ
diff --git a/app/src/main/res/mipmap-xxxhdpi/ic_launcher_adaptive_back.png b/app/src/main/res/mipmap-xxxhdpi/ic_launcher_adaptive_back.png
deleted file mode 100644
index f15c745c..00000000
Binary files a/app/src/main/res/mipmap-xxxhdpi/ic_launcher_adaptive_back.png and /dev/null differ
diff --git a/app/src/main/res/mipmap-xxxhdpi/ic_launcher_adaptive_fore.png b/app/src/main/res/mipmap-xxxhdpi/ic_launcher_adaptive_fore.png
deleted file mode 100644
index d11b606c..00000000
Binary files a/app/src/main/res/mipmap-xxxhdpi/ic_launcher_adaptive_fore.png and /dev/null differ
diff --git a/app/src/main/res/mipmap-xxxhdpi/ic_launcher_foreground.png b/app/src/main/res/mipmap-xxxhdpi/ic_launcher_foreground.png
new file mode 100644
index 00000000..67a60b27
Binary files /dev/null and b/app/src/main/res/mipmap-xxxhdpi/ic_launcher_foreground.png differ
diff --git a/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png b/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png
new file mode 100644
index 00000000..860c0c32
Binary files /dev/null and b/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png differ
diff --git a/app/src/main/res/values-night/themes.xml b/app/src/main/res/values-night/themes.xml
index 19c9f851..b0996c61 100644
--- a/app/src/main/res/values-night/themes.xml
+++ b/app/src/main/res/values-night/themes.xml
@@ -2,8 +2,8 @@