diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index e85bc2fa1e8a08aab16e5ecee17f558d0241aa62..1b0744a4caf1c2a64cbef16da8a6b9cfaa005cc0 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -43,7 +43,7 @@ qt_target_qml_sources(${PROJECT_NAME}
         "/"
     RESOURCES
         fonts/QtOneIconFont.ttf
-        images/appicon.png
+        images/appicon.svg
 )
 
 target_link_libraries(${PROJECT_NAME} PRIVATE
diff --git a/src/HomePage.qml b/src/HomePage.qml
index 7d5f1441f00d7150ffa0cf6f494c2e3d41ddd72a..d00944a69d5df750580fe82a7022af5619bf95cb 100644
--- a/src/HomePage.qml
+++ b/src/HomePage.qml
@@ -53,7 +53,7 @@ Flickable {
 
                 Image {
                     id: qdsLogo
-                    source: "/images/appicon.png"
+                    source: "/images/appicon.svg"
                     fillMode: Image.PreserveAspectFit
                     Layout.preferredWidth: 64
                     Layout.preferredHeight: 64
diff --git a/src/Main.qml b/src/Main.qml
index e29a59f251c3f53c4f7c546ea42c7d5288058ba5..5b8586289eecf98313e2fc5caeb807528326d4a5 100644
--- a/src/Main.qml
+++ b/src/Main.qml
@@ -107,4 +107,66 @@ Rectangle {
             }
         }
     }
+
+    Popup {
+        id: popup
+        width: 250
+        height: 75
+        modal: true
+        visible: false
+
+        anchors.centerIn: parent
+
+        Rectangle {
+            anchors.fill: parent
+            color: "white"
+
+            Text {
+                id: popupText
+                anchors.centerIn: parent
+            }
+        }
+
+        ProgressBar {
+            id: progressBar
+            anchors.bottom: parent.bottom
+            anchors.left: parent.left
+            anchors.right: parent.right
+            height: 2
+            visible: true
+            indeterminate: true
+        }
+
+        Timer {
+            id: timer
+            repeat: false
+            running: popup.visible
+            onTriggered: {
+                popup.visible = false
+            }
+        }
+
+        Connections {
+            target: backend
+            function onPopupOpen(text, timeout) {
+                popup.visible = true
+                popupText.text = text
+                timer.interval = timeout
+                timer.running = timeout <= 0
+            }
+
+            function onPopupClose() {
+                popup.visible = false
+            }
+
+            function onPopupTextChanged(text) {
+                console.log("Popup text changed", text)
+                popupText.text = text
+            }
+
+            function onPopupProgressIndeterminateChanged(indeterminate) {
+                progressBar.indeterminate = indeterminate
+            }
+        }
+    }
 }
diff --git a/src/android/AndroidManifest.xml.in b/src/android/AndroidManifest.xml.in
index 8c1eec4df743ac2619ddddba838cb7355e8f0c4d..66404269f7989f36320661583912cb2d1603693b 100644
--- a/src/android/AndroidManifest.xml.in
+++ b/src/android/AndroidManifest.xml.in
@@ -3,10 +3,11 @@
     android:installLocation="auto" android:versionCode="@GOOGLE_PLAY_APP_VERSION@"
     android:versionName="@CMAKE_VAR_GIT_VERSION@">
     <!-- %%INSERT_PERMISSIONS -->
+    <uses-permission android:name="android.permission.WAKE_LOCK" />
     <!-- %%INSERT_FEATURES -->
     <supports-screens android:anyDensity="true" android:largeScreens="true"
         android:normalScreens="true" android:smallScreens="true" />
-    <application android:icon="@mipmap/app_icon"
+    <application android:icon="@mipmap/ic_launcher"
         android:name="org.qtproject.qt.android.bindings.QtApplication"
         android:extractNativeLibs="true" android:hardwareAccelerated="true"
         android:label="Qt UI Viewer" android:requestLegacyExternalStorage="true"
@@ -16,7 +17,7 @@
             android:configChanges="orientation|uiMode|screenLayout|screenSize|smallestScreenSize|layoutDirection|locale|fontScale|keyboard|keyboardHidden|navigation|mcc|mnc|density"
             android:label="Qt UI Viewer" android:launchMode="singleTask"
             android:screenOrientation="unspecified" android:exported="true"
-            android:windowSoftInputMode="adjustResize">
+            android:windowSoftInputMode="adjustResize" android:keepScreenOn="true">
             <intent-filter>
                 <action android:name="android.intent.action.MAIN" />
                 <category android:name="android.intent.category.LAUNCHER" />
diff --git a/src/android/res/drawable/ic_launcher_background.xml b/src/android/res/drawable/ic_launcher_background.xml
new file mode 100644
index 0000000000000000000000000000000000000000..e3c2454e06fb6ae5cb0f94109492d3b473966a16
--- /dev/null
+++ b/src/android/res/drawable/ic_launcher_background.xml
@@ -0,0 +1,26 @@
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:aapt="http://schemas.android.com/aapt"
+    android:width="108dp"
+    android:height="108dp"
+    android:viewportWidth="108"
+    android:viewportHeight="108">
+  <group android:scaleX="0.99"
+      android:scaleY="0.99"
+      android:translateX="0.54"
+      android:translateY="0.54">
+    <path
+        android:pathData="M0,13.5V108H94.5L108,94.5V0H13.5L0,13.5Z">
+      <aapt:attr name="android:fillColor">
+        <gradient 
+            android:startX="104.99"
+            android:startY="-26.62"
+            android:endX="11.55"
+            android:endY="126.08"
+            android:type="linear">
+          <item android:offset="0.14" android:color="#FF014B57"/>
+          <item android:offset="1" android:color="#FF0F7080"/>
+        </gradient>
+      </aapt:attr>
+    </path>
+  </group>
+</vector>
diff --git a/src/android/res/drawable/ic_launcher_foreground.xml b/src/android/res/drawable/ic_launcher_foreground.xml
new file mode 100644
index 0000000000000000000000000000000000000000..f09532519c052b3af27d99d52b060696fe593a5d
--- /dev/null
+++ b/src/android/res/drawable/ic_launcher_foreground.xml
@@ -0,0 +1,18 @@
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+    android:width="108dp"
+    android:height="108dp"
+    android:viewportWidth="108"
+    android:viewportHeight="108">
+  <group android:scaleX="0.66"
+      android:scaleY="0.66"
+      android:translateX="17.37"
+      android:translateY="17.04">
+    <group>
+      <clip-path
+          android:pathData="M0.25,0.13h107.75v107.75h-107.75z"/>
+      <path
+          android:pathData="M28.84,62.54C28.84,67.29 31.25,69.66 36.08,69.66C40.91,69.66 43.33,67.29 43.33,62.54V35.42H51.59V62.36C51.59,67.35 50.29,71.02 47.69,73.37C45.14,75.69 41.27,76.84 36.08,76.84C30.89,76.84 27,75.69 24.41,73.37C21.85,71.02 20.58,67.35 20.58,62.36V35.42H28.84V62.54ZM82.13,35.42H90.81L81.35,76.13H66.09L56.63,35.42H65.31L72.38,68.94H75.07L82.13,35.42Z"
+          android:fillColor="#2CDE85"/>
+    </group>
+  </group>
+</vector>
diff --git a/src/android/res/mipmap-anydpi-v26/ic_launcher.xml b/src/android/res/mipmap-anydpi-v26/ic_launcher.xml
new file mode 100644
index 0000000000000000000000000000000000000000..bbd3e021239ce758474da78cfc2ca3cf85ed0d91
--- /dev/null
+++ b/src/android/res/mipmap-anydpi-v26/ic_launcher.xml
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="utf-8"?>
+<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
+    <background android:drawable="@drawable/ic_launcher_background"/>
+    <foreground android:drawable="@drawable/ic_launcher_foreground"/>
+</adaptive-icon>
\ No newline at end of file
diff --git a/src/android/res/mipmap-anydpi-v26/ic_launcher_round.xml b/src/android/res/mipmap-anydpi-v26/ic_launcher_round.xml
new file mode 100644
index 0000000000000000000000000000000000000000..bbd3e021239ce758474da78cfc2ca3cf85ed0d91
--- /dev/null
+++ b/src/android/res/mipmap-anydpi-v26/ic_launcher_round.xml
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="utf-8"?>
+<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
+    <background android:drawable="@drawable/ic_launcher_background"/>
+    <foreground android:drawable="@drawable/ic_launcher_foreground"/>
+</adaptive-icon>
\ No newline at end of file
diff --git a/src/android/res/mipmap-hdpi/app_icon.png b/src/android/res/mipmap-hdpi/app_icon.png
deleted file mode 100644
index 74a188d073456264ab840da9314a48447fc95fcf..0000000000000000000000000000000000000000
Binary files a/src/android/res/mipmap-hdpi/app_icon.png and /dev/null differ
diff --git a/src/android/res/mipmap-hdpi/ic_launcher.webp b/src/android/res/mipmap-hdpi/ic_launcher.webp
new file mode 100644
index 0000000000000000000000000000000000000000..45b059ae192f60f60ed2303339c36c294dbbfc3e
Binary files /dev/null and b/src/android/res/mipmap-hdpi/ic_launcher.webp differ
diff --git a/src/android/res/mipmap-hdpi/ic_launcher_round.webp b/src/android/res/mipmap-hdpi/ic_launcher_round.webp
new file mode 100644
index 0000000000000000000000000000000000000000..6478dcebfebd3dd0c861fa21138c69bc168fffc9
Binary files /dev/null and b/src/android/res/mipmap-hdpi/ic_launcher_round.webp differ
diff --git a/src/android/res/mipmap-ldpi/app_icon.png b/src/android/res/mipmap-ldpi/app_icon.png
deleted file mode 100644
index a52520e2630446955333139ca069431c38b75376..0000000000000000000000000000000000000000
Binary files a/src/android/res/mipmap-ldpi/app_icon.png and /dev/null differ
diff --git a/src/android/res/mipmap-mdpi/app_icon.png b/src/android/res/mipmap-mdpi/app_icon.png
deleted file mode 100644
index 36a356c0cec907702d1ecd5562586ca8ee72325c..0000000000000000000000000000000000000000
Binary files a/src/android/res/mipmap-mdpi/app_icon.png and /dev/null differ
diff --git a/src/android/res/mipmap-mdpi/ic_launcher.webp b/src/android/res/mipmap-mdpi/ic_launcher.webp
new file mode 100644
index 0000000000000000000000000000000000000000..f023c33ba54629232b36c2efda70367edc74dd99
Binary files /dev/null and b/src/android/res/mipmap-mdpi/ic_launcher.webp differ
diff --git a/src/android/res/mipmap-mdpi/ic_launcher_round.webp b/src/android/res/mipmap-mdpi/ic_launcher_round.webp
new file mode 100644
index 0000000000000000000000000000000000000000..a3cc2d08d9da07471aba193ffefba9328d3299aa
Binary files /dev/null and b/src/android/res/mipmap-mdpi/ic_launcher_round.webp differ
diff --git a/src/android/res/mipmap-xhdpi/app_icon.png b/src/android/res/mipmap-xhdpi/app_icon.png
deleted file mode 100644
index e1f2e9dc1f2653cdb78f3392df37664615f811aa..0000000000000000000000000000000000000000
Binary files a/src/android/res/mipmap-xhdpi/app_icon.png and /dev/null differ
diff --git a/src/android/res/mipmap-xhdpi/ic_launcher.webp b/src/android/res/mipmap-xhdpi/ic_launcher.webp
new file mode 100644
index 0000000000000000000000000000000000000000..0c33762a480bca1d329d2b90252297fdb106b8e6
Binary files /dev/null and b/src/android/res/mipmap-xhdpi/ic_launcher.webp differ
diff --git a/src/android/res/mipmap-xhdpi/ic_launcher_round.webp b/src/android/res/mipmap-xhdpi/ic_launcher_round.webp
new file mode 100644
index 0000000000000000000000000000000000000000..6599d9b307275916df8e1da8a74c6ad9917fbf02
Binary files /dev/null and b/src/android/res/mipmap-xhdpi/ic_launcher_round.webp differ
diff --git a/src/android/res/mipmap-xxhdpi/app_icon.png b/src/android/res/mipmap-xxhdpi/app_icon.png
deleted file mode 100644
index 652a8e9b7e4e7ebb31424805025b1a2bce8e708d..0000000000000000000000000000000000000000
Binary files a/src/android/res/mipmap-xxhdpi/app_icon.png and /dev/null differ
diff --git a/src/android/res/mipmap-xxhdpi/ic_launcher.webp b/src/android/res/mipmap-xxhdpi/ic_launcher.webp
new file mode 100644
index 0000000000000000000000000000000000000000..bb3c5ea66b3356bf2195068b3dc4a6d8b6466a12
Binary files /dev/null and b/src/android/res/mipmap-xxhdpi/ic_launcher.webp differ
diff --git a/src/android/res/mipmap-xxhdpi/ic_launcher_round.webp b/src/android/res/mipmap-xxhdpi/ic_launcher_round.webp
new file mode 100644
index 0000000000000000000000000000000000000000..001d3b0de54aa94df573dc740f0d45ea2e8f245b
Binary files /dev/null and b/src/android/res/mipmap-xxhdpi/ic_launcher_round.webp differ
diff --git a/src/android/res/mipmap-xxxhdpi/app_icon.png b/src/android/res/mipmap-xxxhdpi/app_icon.png
deleted file mode 100644
index 7a404f6cbb8e0acc99545092319bea31c384ecca..0000000000000000000000000000000000000000
Binary files a/src/android/res/mipmap-xxxhdpi/app_icon.png and /dev/null differ
diff --git a/src/android/res/mipmap-xxxhdpi/ic_launcher.webp b/src/android/res/mipmap-xxxhdpi/ic_launcher.webp
new file mode 100644
index 0000000000000000000000000000000000000000..c60e7e17d4c43dfa63500e0bf30802ddfc1fbd46
Binary files /dev/null and b/src/android/res/mipmap-xxxhdpi/ic_launcher.webp differ
diff --git a/src/android/res/mipmap-xxxhdpi/ic_launcher_round.webp b/src/android/res/mipmap-xxxhdpi/ic_launcher_round.webp
new file mode 100644
index 0000000000000000000000000000000000000000..a41bd7a2b444bd7108df57d4334afc50bc5ae025
Binary files /dev/null and b/src/android/res/mipmap-xxxhdpi/ic_launcher_round.webp differ
diff --git a/src/android/res/values/strings.xml b/src/android/res/values/strings.xml
new file mode 100644
index 0000000000000000000000000000000000000000..004d0188e87976edca44fd1c4e4b3cd1c8469571
--- /dev/null
+++ b/src/android/res/values/strings.xml
@@ -0,0 +1,18 @@
+<!--
+  ~ Copyright (C) 2023 The Android Open Source Project
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~     https://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License.
+  -->
+<resources>
+    <string name="app_name">Qt UI Viewer</string>
+</resources>
diff --git a/src/backend/backend.cpp b/src/backend/backend.cpp
index 400b8e1bf8221382cafd81d61c014bdadba60e9a..e23fab4ac5a8b701c47afd3f88b8357318dfcdbc 100644
--- a/src/backend/backend.cpp
+++ b/src/backend/backend.cpp
@@ -184,8 +184,7 @@ void Backend::connectDesignStudio(const QString &ipAddr)
 
 void Backend::runProject(const QString &id, const QByteArray &projectData)
 {
-    emit popupOpen();
-    updatePopup("Running project...");
+    emit popupOpen("Running project...");
 
     // we'll use this to notify the correct DS when the project started/stopped
     m_lastProjectSenderId = id;
diff --git a/src/backend/dsconnector/ds.cpp b/src/backend/dsconnector/ds.cpp
index c95ec8cc78b1e3e99a45076b56eca41ff86f18b6..b6817517b7c42558f0e982522c2a648452adfb79 100644
--- a/src/backend/dsconnector/ds.cpp
+++ b/src/backend/dsconnector/ds.cpp
@@ -14,31 +14,40 @@ DesignStudio::DesignStudio(QWebSocket *socket, const QString &m_deviceUuid, QObj
 {
     initPingPong();
     initSocket();
+
+    m_pingTimer.start();
 }
 
 void DesignStudio::initPingPong()
 {
+    m_pingTimer.setInterval(1000);
+    m_pongTimer.setInterval(10000);
+    m_pongTimer.setSingleShot(true);
+    m_pingTimer.setSingleShot(true);
+
     connect(&m_pingTimer, &QTimer::timeout, this, [this]() {
         m_socket->ping();
-        m_pongTimer.start(15000);
+        m_pongTimer.start();
     });
 
     connect(m_socket.data(),
             &QWebSocket::pong,
             this,
-            [this](quint64 elapsedTime, const QByteArray &) { m_pongTimer.stop(); });
+            [this](quint64 elapsedTime, const QByteArray &) {
+                m_pongTimer.stop();
+                m_pingTimer.start();
+            });
 
     connect(&m_pongTimer, &QTimer::timeout, this, [this]() {
-        qDebug() << "Design Studio" << m_id << "is not responding. Reconnecting.";
+        qDebug() << "Design Studio" << m_id << "is not responding. Closing the connection.";
         m_socket->close();
+        m_socket->abort();
+        emit disconnected(m_id);
     });
 }
 
 void DesignStudio::initSocket()
 {
-    m_pingTimer.start(15000);
-    m_pongTimer.stop();
-
     connect(m_socket.data(), &QWebSocket::disconnected, this, [this]() {
         qDebug() << "Design Studio" << m_id << "disconnected";
         m_pingTimer.stop();
diff --git a/src/images/appicon.png b/src/images/appicon.png
deleted file mode 100644
index 7d3104bb76c4fdcad3d9028b044318100806f5be..0000000000000000000000000000000000000000
Binary files a/src/images/appicon.png and /dev/null differ
diff --git a/src/images/appicon.svg b/src/images/appicon.svg
new file mode 100644
index 0000000000000000000000000000000000000000..eeea63261ef72d666e375b298c0f710198bb0df7
--- /dev/null
+++ b/src/images/appicon.svg
@@ -0,0 +1,44 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<svg id="Layer_1" data-name="Layer 1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 64 64">
+  <defs>
+    <style>
+      .cls-1 {
+        fill: none;
+      }
+
+      .cls-2 {
+        fill: url(#linear-gradient);
+      }
+
+      .cls-3 {
+        clip-path: url(#clippath-1);
+      }
+
+      .cls-4 {
+        fill: #2cde85;
+      }
+
+      .cls-5 {
+        clip-path: url(#clippath);
+      }
+    </style>
+    <clipPath id="clippath">
+      <rect class="cls-1" width="64" height="64"/>
+    </clipPath>
+    <linearGradient id="linear-gradient" x1="61.5" y1="80.21" x2="6.13" y2="-10.28" gradientTransform="translate(0 64) scale(1 -1)" gradientUnits="userSpaceOnUse">
+      <stop offset=".14" stop-color="#014b57"/>
+      <stop offset="1" stop-color="#0f7080"/>
+    </linearGradient>
+    <clipPath id="clippath-1">
+      <rect class="cls-1" x=".15" width="64" height="64"/>
+    </clipPath>
+  </defs>
+  <g class="cls-5">
+    <g>
+      <path class="cls-2" d="M0,8v56h56l8-8V0H8L0,8Z"/>
+      <g class="cls-3">
+        <path class="cls-4" d="M17.06,36.71c0,2.75,1.48,4.13,4.44,4.13s4.44-1.38,4.44-4.13v-15.71h5.06v15.61c0,2.89-.79,5.02-2.38,6.38-1.56,1.34-3.94,2.01-7.12,2.01s-5.56-.67-7.15-2.01c-1.57-1.36-2.35-3.49-2.35-6.38v-15.61h5.06v15.71ZM48.67,21h5.33l-5.81,24h-9.38l-5.81-24h5.33l4.34,19.76h1.65l4.34-19.76Z"/>
+      </g>
+    </g>
+  </g>
+</svg>
\ No newline at end of file