{"id":13389,"date":"2026-10-05T20:49:04","date_gmt":"2026-10-05T20:49:04","guid":{"rendered":"https:\/\/www.hovatek.com\/blog\/?p=13389"},"modified":"2026-10-06T15:14:50","modified_gmt":"2026-10-06T15:14:50","slug":"how-i-tried-to-control-samsung-galaxy-a12-floating-windows-using-adb","status":"publish","type":"post","link":"https:\/\/www.hovatek.com\/blog\/how-i-tried-to-control-samsung-galaxy-a12-floating-windows-using-adb\/","title":{"rendered":"How I Tried to Control Samsung Galaxy A12 Floating Windows Using ADB"},"content":{"rendered":"\r\n<p class=\"wp-block-paragraph\">I already knew that the Samsung Galaxy A12 could open applications in floating windows using the phone&#8217;s touchscreen interface. What I wanted to find out was whether I could control those same floating windows from a computer using ADB.<\/p>\r\n\r\n\r\n\r\n<p class=\"wp-block-paragraph\">The idea came from the old TV channel-mosaic feature, where several television channels could be displayed on the screen at the same time. Instead of TV channels, I wanted to see whether I could arrange several Android applications on the Galaxy A12 display, with ADB controlling their positions and sizes.<\/p>\r\n\r\n\r\n\r\n<p class=\"wp-block-paragraph\">My original target was a six-window arrangement: three applications across the top and another three across the bottom.<\/p>\r\n\r\n\r\n\r\n<p class=\"wp-block-paragraph\">I also used scrcpy during the experiment to mirror the Galaxy A12 display on my computer. This became important because an ADB command could execute without an obvious error while the result on the phone was not necessarily what I expected.<\/p>\r\n\r\n\r\n\r\n<p class=\"wp-block-paragraph\">What started as a fairly simple window-resizing experiment eventually became an investigation into Android tasks, freeform windowing, minimum window sizes, logical display density and Samsung&#8217;s limit on the number of simultaneously visible floating windows.<\/p>\r\n\r\n\r\n\r\n<h2 class=\"wp-block-heading\">1. Connecting the Samsung Galaxy A12 to ADB<\/h2>\r\n\r\n\r\n\r\n<p class=\"wp-block-paragraph\">I started by connecting the Galaxy A12 to my computer with USB debugging enabled and checking whether ADB could communicate with it.<\/p>\r\n\r\n\r\n\r\n<pre class=\"wp-block-code\"><code>adb devices<\/code><\/pre>\r\n\r\n\r\n\r\n<p class=\"wp-block-paragraph\">The phone appeared in the device list with <code>device<\/code> beside its serial number, confirming that the ADB connection was working.<\/p>\r\n\r\n\r\n\r\n<p class=\"wp-block-paragraph\">I then checked the phone model, Android version and build:<\/p>\r\n\r\n\r\n\r\n<pre class=\"wp-block-code\"><code>adb shell getprop ro.product.model\r\nadb shell getprop ro.build.version.release\r\nadb shell getprop ro.build.display.id<\/code><\/pre>\r\n\r\n\r\n\r\n<p class=\"wp-block-paragraph\">The phone returned:<\/p>\r\n\r\n\r\n\r\n<ul class=\"wp-block-list\">\r\n<li>Model: <code>SM-A125F<\/code><\/li>\r\n<li>Android version: <code>12<\/code><\/li>\r\n<li>Build: <code>SP1A.210812.016.A125FXXS5CXE3<\/code><\/li>\r\n<\/ul>\r\n\r\n\r\n\r\n<p class=\"wp-block-paragraph\"><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-13367\" src=\"https:\/\/hovatek.com\/blog\/bpyeki\/uploads\/2026\/10\/samsung-adb-connection.png\" alt=\"Samsung Galaxy A12 connected to ADB showing model SM-A125F, Android 12 and build information in Command Prompt\" width=\"1735\" height=\"907\" srcset=\"https:\/\/www.hovatek.com\/blog\/bpyeki\/uploads\/2026\/10\/samsung-adb-connection.png 1735w, https:\/\/www.hovatek.com\/blog\/bpyeki\/uploads\/2026\/10\/samsung-adb-connection-768x401.png 768w, https:\/\/www.hovatek.com\/blog\/bpyeki\/uploads\/2026\/10\/samsung-adb-connection-1536x803.png 1536w\" sizes=\"auto, (max-width: 1735px) 100vw, 1735px\" \/><\/p>\r\n\r\n\r\n\r\n<p class=\"wp-block-paragraph\">This established the environment I was working with before I started changing anything.<\/p>\r\n\r\n\r\n\r\n<h2 class=\"wp-block-heading\">2. Mirroring the Galaxy A12 With scrcpy<\/h2>\r\n\r\n\r\n\r\n<p class=\"wp-block-paragraph\">Command Prompt could show me whether an ADB command had been accepted, but it could not always tell me what had actually happened visually on the phone.<\/p>\r\n\r\n\r\n\r\n<p class=\"wp-block-paragraph\">For that reason, I used scrcpy to mirror the Galaxy A12 display on my computer.<\/p>\r\n\r\n\r\n\r\n<p class=\"wp-block-paragraph\">With the phone connected through USB and USB debugging enabled, I opened a terminal in the scrcpy folder and ran:<\/p>\r\n\r\n\r\n\r\n<pre class=\"wp-block-code\"><code>scrcpy<\/code><\/pre>\r\n\r\n\r\n\r\n<p class=\"wp-block-paragraph\"><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-13366\" src=\"https:\/\/hovatek.com\/blog\/bpyeki\/uploads\/2026\/10\/samsung-galaxy-a12-scrcpy.png\" alt=\"Samsung Galaxy A12 screen mirrored on a Windows computer using scrcpy during an ADB freeform window experiment\" width=\"1667\" height=\"944\" srcset=\"https:\/\/www.hovatek.com\/blog\/bpyeki\/uploads\/2026\/10\/samsung-galaxy-a12-scrcpy.png 1667w, https:\/\/www.hovatek.com\/blog\/bpyeki\/uploads\/2026\/10\/samsung-galaxy-a12-scrcpy-768x435.png 768w, https:\/\/www.hovatek.com\/blog\/bpyeki\/uploads\/2026\/10\/samsung-galaxy-a12-scrcpy-1536x870.png 1536w\" sizes=\"auto, (max-width: 1667px) 100vw, 1667px\" \/> This opened the Galaxy A12 display in a window on the computer. I could place scrcpy beside Command Prompt and watch what happened on the phone while running ADB commands.<\/p>\r\n\r\n\r\n\r\n<p class=\"wp-block-paragraph\">This turned out to be particularly useful later because I could capture both the ADB command and the corresponding change on the phone in the same screenshot.<\/p>\r\n\r\n\r\n\r\n<h2 class=\"wp-block-heading\">3. Enabling Freeform Window Support<\/h2>\r\n\r\n\r\n\r\n<p class=\"wp-block-paragraph\">The Galaxy A12 could already create floating windows through Samsung&#8217;s touchscreen interface. My goal was to see how much of the underlying functionality I could control through ADB.<\/p>\r\n\r\n\r\n\r\n<p class=\"wp-block-paragraph\">I enabled Android&#8217;s freeform-related settings with:<\/p>\r\n\r\n\r\n\r\n<pre class=\"wp-block-code\"><code>adb shell settings put global enable_freeform_support 1\r\nadb shell settings put global force_resizable_activities 1<\/code><\/pre>\r\n\r\n\r\n\r\n<p class=\"wp-block-paragraph\">I then checked both settings:<\/p>\r\n\r\n\r\n\r\n<pre class=\"wp-block-code\"><code>adb shell settings get global enable_freeform_support\r\nadb shell settings get global force_resizable_activities<\/code><\/pre>\r\n\r\n\r\n\r\n<p class=\"wp-block-paragraph\">Both returned:<\/p>\r\n\r\n\r\n\r\n<pre class=\"wp-block-code\"><code>1<\/code><\/pre>\r\n\r\n\r\n\r\n<p class=\"wp-block-paragraph\">This confirmed that the freeform support and force-resizable settings had been enabled.<\/p>\r\n\r\n\r\n\r\n<p class=\"wp-block-paragraph\">At this point, however, I had not yet proved that every application I launched would actually become a freeform task.<\/p>\r\n\r\n\r\n\r\n<h2 class=\"wp-block-heading\">4. Opening the Applications for the Multi-Window Test<\/h2>\r\n\r\n\r\n\r\n<p class=\"wp-block-paragraph\">Before trying to arrange a grid, I needed several applications running.<\/p>\r\n\r\n\r\n\r\n<p class=\"wp-block-paragraph\">I checked the packages installed on the phone:<\/p>\r\n\r\n\r\n\r\n<pre class=\"wp-block-code\"><code>adb shell pm list packages<\/code><\/pre>\r\n\r\n\r\n\r\n<p class=\"wp-block-paragraph\"><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-13370\" src=\"https:\/\/hovatek.com\/blog\/bpyeki\/uploads\/2026\/10\/samsung-galaxy-list-packages.png\" alt=\"ADB package list on Samsung Galaxy A12 showing installed apps used for the freeform window experiment\" width=\"1740\" height=\"904\" srcset=\"https:\/\/www.hovatek.com\/blog\/bpyeki\/uploads\/2026\/10\/samsung-galaxy-list-packages.png 1740w, https:\/\/www.hovatek.com\/blog\/bpyeki\/uploads\/2026\/10\/samsung-galaxy-list-packages-768x399.png 768w, https:\/\/www.hovatek.com\/blog\/bpyeki\/uploads\/2026\/10\/samsung-galaxy-list-packages-1536x798.png 1536w\" sizes=\"auto, (max-width: 1740px) 100vw, 1740px\" \/> Among the applications I selected were Chrome, YouTube, Google Play Store, Samsung Gallery and Facebook. I also used Android Settings as the sixth application.<\/p>\r\n\r\n\r\n\r\n<p class=\"wp-block-paragraph\">The relevant package names were:<\/p>\r\n\r\n\r\n\r\n<pre class=\"wp-block-code\"><code>com.android.chrome\r\ncom.google.android.youtube\r\ncom.android.vending\r\ncom.sec.android.gallery3d\r\ncom.facebook.katana\r\ncom.android.settings<\/code><\/pre>\r\n\r\n\r\n\r\n<p class=\"wp-block-paragraph\">I explicitly requested freeform mode when launching Settings:<\/p>\r\n\r\n\r\n\r\n<pre class=\"wp-block-code\"><code>adb shell am start --windowingMode 5 -n com.android.settings\/.Settings<\/code><\/pre>\r\n\r\n\r\n\r\n<p class=\"wp-block-paragraph\"><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-13363\" src=\"https:\/\/hovatek.com\/blog\/bpyeki\/uploads\/2026\/10\/samsung-a12-settings-freeform-adb.png\" alt=\"ADB command launching Samsung Galaxy A12 Settings in freeform windowing mode 5\" width=\"1755\" height=\"896\" srcset=\"https:\/\/www.hovatek.com\/blog\/bpyeki\/uploads\/2026\/10\/samsung-a12-settings-freeform-adb.png 1755w, https:\/\/www.hovatek.com\/blog\/bpyeki\/uploads\/2026\/10\/samsung-a12-settings-freeform-adb-768x392.png 768w, https:\/\/www.hovatek.com\/blog\/bpyeki\/uploads\/2026\/10\/samsung-a12-settings-freeform-adb-1536x784.png 1536w\" sizes=\"auto, (max-width: 1755px) 100vw, 1755px\" \/> I initially launched the other five applications using their package names:<\/p>\r\n\r\n\r\n\r\n<pre class=\"wp-block-code\"><code>adb shell monkey -p com.android.chrome 1\r\nadb shell monkey -p com.google.android.youtube 1\r\nadb shell monkey -p com.android.vending 1\r\nadb shell monkey -p com.sec.android.gallery3d 1\r\nadb shell monkey -p com.facebook.katana 1<\/code><\/pre>\r\n\r\n\r\n\r\n<p class=\"wp-block-paragraph\">Each command returned <code>Events injected: 1<\/code>.<\/p>\r\n\r\n\r\n\r\n<p class=\"wp-block-paragraph\"><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-13358\" src=\"https:\/\/hovatek.com\/blog\/bpyeki\/uploads\/2026\/10\/launch-android-apps-adb-samsung-a12.png\" alt=\"ADB commands launching Chrome, YouTube, Play Store, Gallery and Facebook on Samsung Galaxy A12\" width=\"1730\" height=\"909\" srcset=\"https:\/\/www.hovatek.com\/blog\/bpyeki\/uploads\/2026\/10\/launch-android-apps-adb-samsung-a12.png 1730w, https:\/\/www.hovatek.com\/blog\/bpyeki\/uploads\/2026\/10\/launch-android-apps-adb-samsung-a12-768x404.png 768w, https:\/\/www.hovatek.com\/blog\/bpyeki\/uploads\/2026\/10\/launch-android-apps-adb-samsung-a12-1536x807.png 1536w\" sizes=\"auto, (max-width: 1730px) 100vw, 1730px\" \/> At first this looked promising, but I later discovered that <code>Events injected: 1<\/code> only confirmed that the launch input had been sent. It did not mean that the application had entered freeform mode.<\/p>\r\n\r\n\r\n\r\n<h2 class=\"wp-block-heading\">5. Discovering That Most of the Apps Were Still Fullscreen<\/h2>\r\n\r\n\r\n\r\n<p class=\"wp-block-paragraph\">I initially thought that once the applications were running, I could start assigning coordinates to them. scrcpy quickly showed that something was wrong. Instead of forming a neat grid, some applications were simply covering others.<\/p>\r\n\r\n\r\n\r\n<p class=\"wp-block-paragraph\">I stopped resizing and checked Android&#8217;s task information:<\/p>\r\n\r\n\r\n\r\n<pre class=\"wp-block-code\"><code>adb shell am stack list<\/code><\/pre>\r\n\r\n\r\n\r\n<p class=\"wp-block-paragraph\"><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-13357\" src=\"https:\/\/hovatek.com\/blog\/bpyeki\/uploads\/2026\/10\/android-task-ids-windowing-modes-adb.png\" alt=\"ADB stack list showing task IDs, window bounds and windowing modes on Samsung Galaxy A12\" width=\"1740\" height=\"904\" srcset=\"https:\/\/www.hovatek.com\/blog\/bpyeki\/uploads\/2026\/10\/android-task-ids-windowing-modes-adb.png 1740w, https:\/\/www.hovatek.com\/blog\/bpyeki\/uploads\/2026\/10\/android-task-ids-windowing-modes-adb-768x399.png 768w, https:\/\/www.hovatek.com\/blog\/bpyeki\/uploads\/2026\/10\/android-task-ids-windowing-modes-adb-1536x798.png 1536w\" sizes=\"auto, (max-width: 1740px) 100vw, 1740px\" \/> After rebooting the phone and repeating the experiment, Settings was assigned task ID <code>105<\/code> and Android reported it as:<\/p>\r\n\r\n\r\n\r\n<pre class=\"wp-block-code\"><code>taskId=105\r\nmWindowingMode=freeform\r\nvisible=true<\/code><\/pre>\r\n\r\n\r\n\r\n<p class=\"wp-block-paragraph\">The other applications were different:<\/p>\r\n\r\n\r\n\r\n<pre class=\"wp-block-code\"><code>Chrome      taskId=106   fullscreen  visible=false\r\nYouTube     taskId=107   fullscreen  visible=false\r\nPlay Store  taskId=109   fullscreen  visible=false\r\nGallery     taskId=110   fullscreen  visible=true\r\nFacebook    taskId=111   fullscreen  visible=true<\/code><\/pre>\r\n\r\n\r\n\r\n<p class=\"wp-block-paragraph\">This explained the overlap.<\/p>\r\n\r\n\r\n\r\n<p class=\"wp-block-paragraph\">Settings was genuinely running as a freeform task, while Chrome, YouTube, Play Store, Gallery and Facebook were still fullscreen tasks.<\/p>\r\n\r\n\r\n\r\n<p class=\"wp-block-paragraph\">The first problem was therefore not the resize command. I first needed to get the other applications into freeform mode.<\/p>\r\n\r\n\r\n\r\n<p class=\"wp-block-paragraph\">This also showed why task IDs should not be hard-coded. Android can assign new IDs when tasks are recreated or the phone is rebooted.<\/p>\r\n\r\n\r\n\r\n<h2 class=\"wp-block-heading\">6. Finding the Correct Launcher Activities<\/h2>\r\n\r\n\r\n\r\n<p class=\"wp-block-paragraph\">Before relaunching the fullscreen applications in freeform mode, I needed their proper launcher activities.<\/p>\r\n\r\n\r\n\r\n<p class=\"wp-block-paragraph\">I had already discovered that copying the current <code>topActivity<\/code> from <code>am stack list<\/code> was not always reliable. Play Store, for example, had an internal activity that produced a <code>SecurityException<\/code> when I tried to launch it directly because it was not exported.<\/p>\r\n\r\n\r\n\r\n<p class=\"wp-block-paragraph\">I therefore asked Android to resolve the normal launcher activity for each package:<\/p>\r\n\r\n\r\n\r\n<pre class=\"wp-block-code\"><code>adb shell cmd package resolve-activity --brief -a android.intent.action.MAIN -c android.intent.category.LAUNCHER com.android.chrome\r\n\r\nadb shell cmd package resolve-activity --brief -a android.intent.action.MAIN -c android.intent.category.LAUNCHER com.google.android.youtube\r\n\r\nadb shell cmd package resolve-activity --brief -a android.intent.action.MAIN -c android.intent.category.LAUNCHER com.android.vending\r\n\r\nadb shell cmd package resolve-activity --brief -a android.intent.action.MAIN -c android.intent.category.LAUNCHER com.sec.android.gallery3d\r\n\r\nadb shell cmd package resolve-activity --brief -a android.intent.action.MAIN -c android.intent.category.LAUNCHER com.facebook.katana<\/code><\/pre>\r\n\r\n\r\n\r\n<p class=\"wp-block-paragraph\">For example, Android resolved Play Store to:<\/p>\r\n\r\n\r\n\r\n<pre class=\"wp-block-code\"><code>com.android.vending\/.AssetBrowserActivity<\/code><\/pre>\r\n\r\n\r\n\r\n<p class=\"wp-block-paragraph\">YouTube resolved to:<\/p>\r\n\r\n\r\n\r\n<pre class=\"wp-block-code\"><code>com.google.android.youtube\/.app.honeycomb.Shell$HomeActivity<\/code><\/pre>\r\n\r\n\r\n\r\n<p class=\"wp-block-paragraph\"><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-13393\" src=\"https:\/\/hovatek.com\/blog\/bpyeki\/uploads\/2026\/10\/ADB-App-Launch-Commands-Explained.png\" alt=\"ADB resolve-activity commands showing launcher activities for Chrome, YouTube, Google Play Store, Samsung Gallery and Facebook on Samsung Galaxy A12\" width=\"1733\" height=\"907\" srcset=\"https:\/\/www.hovatek.com\/blog\/bpyeki\/uploads\/2026\/10\/ADB-App-Launch-Commands-Explained.png 1733w, https:\/\/www.hovatek.com\/blog\/bpyeki\/uploads\/2026\/10\/ADB-App-Launch-Commands-Explained-768x402.png 768w, https:\/\/www.hovatek.com\/blog\/bpyeki\/uploads\/2026\/10\/ADB-App-Launch-Commands-Explained-1536x804.png 1536w\" sizes=\"auto, (max-width: 1733px) 100vw, 1733px\" \/><\/p>\r\n<p>This gave me proper launcher components to work with instead of guessing activity names.<\/p>\r\n\r\n\r\n\r\n<h2 class=\"wp-block-heading\">7. Relaunching the Apps in Freeform Mode<\/h2>\r\n\r\n\r\n\r\n<p class=\"wp-block-paragraph\">Once I had the correct components, I could stop the existing fullscreen tasks and relaunch the applications while explicitly requesting Android&#8217;s freeform windowing mode.<\/p>\r\n\r\n\r\n\r\n<p class=\"wp-block-paragraph\">For Chrome, I used:<\/p>\r\n\r\n\r\n\r\n<pre class=\"wp-block-code\"><code>adb shell am force-stop com.android.chrome\r\nadb shell am start --windowingMode 5 -n com.android.chrome\/com.google.android.apps.chrome.Main<\/code><\/pre>\r\n\r\n\r\n\r\n<p class=\"wp-block-paragraph\">Chrome was subsequently reported as a genuine freeform task.<\/p>\r\n\r\n\r\n\r\n<p class=\"wp-block-paragraph\">For Play Store, I used the launcher activity Android had resolved:<\/p>\r\n\r\n\r\n\r\n<pre class=\"wp-block-code\"><code>adb shell am force-stop com.android.vending\r\nadb shell am start --windowingMode 5 -n com.android.vending\/.AssetBrowserActivity<\/code><\/pre>\r\n\r\n\r\n\r\n<p class=\"wp-block-paragraph\">Play Store also appeared in the task list with <code>mWindowingMode=freeform<\/code>.<\/p>\r\n\r\n\r\n\r\n<p class=\"wp-block-paragraph\">For Samsung Gallery, I used:<\/p>\r\n\r\n\r\n\r\n<pre class=\"wp-block-code\"><code>adb shell am force-stop com.sec.android.gallery3d\r\nadb shell am start --windowingMode 5 -n com.sec.android.gallery3d\/com.samsung.android.gallery.app.activity.GalleryActivity<\/code><\/pre>\r\n\r\n\r\n\r\n<p class=\"wp-block-paragraph\">For Facebook, I used:<\/p>\r\n\r\n\r\n\r\n<pre class=\"wp-block-code\"><code>adb shell am force-stop com.facebook.katana\r\nadb shell am start --windowingMode 5 -n com.facebook.katana\/com.facebook.katana.LoginActivity<\/code><\/pre>\r\n\r\n\r\n\r\n<p class=\"wp-block-paragraph\"><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-13356\" src=\"https:\/\/hovatek.com\/blog\/bpyeki\/uploads\/2026\/10\/android-freeform-apps-adb-samsung-a12.png\" alt=\"ADB commands relaunching Chrome, Google Play Store, Samsung Gallery and Facebook in freeform mode on Samsung Galaxy A12\" width=\"1768\" height=\"890\" srcset=\"https:\/\/www.hovatek.com\/blog\/bpyeki\/uploads\/2026\/10\/android-freeform-apps-adb-samsung-a12.png 1768w, https:\/\/www.hovatek.com\/blog\/bpyeki\/uploads\/2026\/10\/android-freeform-apps-adb-samsung-a12-768x387.png 768w, https:\/\/www.hovatek.com\/blog\/bpyeki\/uploads\/2026\/10\/android-freeform-apps-adb-samsung-a12-1536x773.png 1536w\" sizes=\"auto, (max-width: 1768px) 100vw, 1768px\" \/><\/p>\r\n<p>YouTube required one extra correction because its launcher activity contained a dollar sign:<\/p>\r\n\r\n\r\n\r\n<pre class=\"wp-block-code\"><code>com.google.android.youtube\/.app.honeycomb.Shell$HomeActivity<\/code><\/pre>\r\n\r\n\r\n\r\n<p class=\"wp-block-paragraph\">My first attempt lost the <code>$HomeActivity<\/code> portion because the Android shell interpreted the dollar sign. The command that preserved the complete component name was:<\/p>\r\n\r\n\r\n\r\n<pre class=\"wp-block-code\"><code>adb shell \"am start --windowingMode 5 -n 'com.google.android.youtube\/.app.honeycomb.Shell$HomeActivity'\"<\/code><\/pre>\r\n\r\n\r\n\r\n<p class=\"wp-block-paragraph\">Android then correctly returned:<\/p>\r\n\r\n\r\n\r\n<pre class=\"wp-block-code\"><code>Starting: Intent { cmp=com.google.android.youtube\/.app.honeycomb.Shell$HomeActivity }<\/code><\/pre>\r\n\r\n\r\n\r\n<p class=\"wp-block-paragraph\">YouTube subsequently appeared as a freeform task as well.<\/p>\r\n\r\n\r\n\r\n<p class=\"wp-block-paragraph\">After each launch, I checked the result with:<\/p>\r\n\r\n\r\n\r\n<pre class=\"wp-block-code\"><code>adb shell am stack list<\/code><\/pre>\r\n\r\n\r\n\r\n<p class=\"wp-block-paragraph\">I only treated an application as successfully converted once Android actually reported <code>mWindowingMode=freeform<\/code>.<\/p>\r\n\r\n\r\n\r\n<h2 class=\"wp-block-heading\">8. Discovering the Five Visible Freeform Window Limit<\/h2>\r\n\r\n\r\n\r\n<p class=\"wp-block-paragraph\">This was where the experiment became particularly interesting.<\/p>\r\n\r\n\r\n\r\n<p class=\"wp-block-paragraph\">After successfully launching YouTube as another freeform task, I checked the task list again.<\/p>\r\n\r\n\r\n\r\n<pre class=\"wp-block-code\"><code>adb shell am stack list<\/code><\/pre>\r\n\r\n\r\n\r\n<p class=\"wp-block-paragraph\">I now had five freeform applications with <code>visible=true<\/code>:<\/p>\r\n\r\n\r\n\r\n<pre class=\"wp-block-code\"><code>YouTube     freeform   visible=true\r\nFacebook    freeform   visible=true\r\nGallery     freeform   visible=true\r\nPlay Store  freeform   visible=true\r\nChrome      freeform   visible=true<\/code><\/pre>\r\n\r\n\r\n\r\n<p class=\"wp-block-paragraph\"><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-13362\" src=\"https:\/\/hovatek.com\/blog\/bpyeki\/uploads\/2026\/10\/samsung-a12-five-visible-freeform-windows.png\" alt=\"ADB task information showing five visible freeform windows on Samsung Galaxy A12 while another freeform task has visible false\" width=\"1748\" height=\"900\" srcset=\"https:\/\/www.hovatek.com\/blog\/bpyeki\/uploads\/2026\/10\/samsung-a12-five-visible-freeform-windows.png 1748w, https:\/\/www.hovatek.com\/blog\/bpyeki\/uploads\/2026\/10\/samsung-a12-five-visible-freeform-windows-768x395.png 768w, https:\/\/www.hovatek.com\/blog\/bpyeki\/uploads\/2026\/10\/samsung-a12-five-visible-freeform-windows-1536x791.png 1536w\" sizes=\"auto, (max-width: 1748px) 100vw, 1748px\" \/><\/p>\r\n<p>Settings had not been converted back to fullscreen or destroyed. It was still a freeform task, but Android now reported:<\/p>\r\n\r\n\r\n\r\n<pre class=\"wp-block-code\"><code>Settings\r\nmWindowingMode=freeform\r\nmAlwaysOnTop=off\r\nvisible=false<\/code><\/pre>\r\n\r\n\r\n\r\n<p class=\"wp-block-paragraph\">This changed my understanding of Samsung&#8217;s five-window restriction.<\/p>\r\n\r\n\r\n\r\n<p class=\"wp-block-paragraph\">The Galaxy A12 was capable of maintaining more than five freeform tasks. The restriction I was seeing appeared to concern how many of those freeform windows could remain visible simultaneously.<\/p>\r\n\r\n\r\n\r\n<p class=\"wp-block-paragraph\">In my test, six freeform tasks existed, but only five had <code>visible=true<\/code>. When YouTube became visible, Settings remained in the task list as a freeform task but changed to <code>visible=false<\/code>.<\/p>\r\n\r\n\r\n\r\n<p class=\"wp-block-paragraph\">scrcpy gave me the visual side of the evidence. I could see YouTube and the other floating applications on the display while Settings was no longer among the visible floating windows.<\/p>\r\n\r\n\r\n\r\n<h2 class=\"wp-block-heading\">9. Confirming That ADB Task Resizing Actually Worked<\/h2>\r\n\r\n\r\n\r\n<p class=\"wp-block-paragraph\">With the applications finally running in genuine freeform mode, I returned to the resizing question.<\/p>\r\n\r\n\r\n\r\n<p class=\"wp-block-paragraph\">Earlier, I had tried resizing Settings while Settings was already hidden. Looking at another application on the phone and expecting it to change obviously did not prove anything.<\/p>\r\n\r\n\r\n\r\n<p class=\"wp-block-paragraph\">I therefore tested the resize command on the currently visible YouTube task.<\/p>\r\n\r\n\r\n\r\n<p class=\"wp-block-paragraph\">At that point YouTube was task <code>117<\/code> and its bounds were:<\/p>\r\n\r\n\r\n\r\n<pre class=\"wp-block-code\"><code>[0,65][684,1585]<\/code><\/pre>\r\n\r\n\r\n\r\n<p class=\"wp-block-paragraph\">I tried:<\/p>\r\n\r\n\r\n\r\n<pre class=\"wp-block-code\"><code>adb shell am task resize 117 0 45 360 785<\/code><\/pre>\r\n\r\n\r\n\r\n<p class=\"wp-block-paragraph\">scrcpy immediately showed YouTube becoming much smaller, proving that the resize operation was actually taking effect.<\/p>\r\n<p><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-13359\" src=\"https:\/\/hovatek.com\/blog\/bpyeki\/uploads\/2026\/10\/resize-youtube-freeform-window-adb.png\" alt=\"ADB task resize command resizing the visible YouTube freeform window on Samsung Galaxy A12\" width=\"1747\" height=\"900\" srcset=\"https:\/\/www.hovatek.com\/blog\/bpyeki\/uploads\/2026\/10\/resize-youtube-freeform-window-adb.png 1747w, https:\/\/www.hovatek.com\/blog\/bpyeki\/uploads\/2026\/10\/resize-youtube-freeform-window-adb-768x396.png 768w, https:\/\/www.hovatek.com\/blog\/bpyeki\/uploads\/2026\/10\/resize-youtube-freeform-window-adb-1536x791.png 1536w\" sizes=\"auto, (max-width: 1747px) 100vw, 1747px\" \/><\/p>\r\n\r\n\r\n\r\n<p class=\"wp-block-paragraph\">However, Android did not use the exact width I had requested.<\/p>\r\n\r\n\r\n\r\n<p class=\"wp-block-paragraph\">I requested:<\/p>\r\n\r\n\r\n\r\n<pre class=\"wp-block-code\"><code>[0,45][360,785]<\/code><\/pre>\r\n\r\n\r\n\r\n<p class=\"wp-block-paragraph\">but <code>am stack list<\/code> reported:<\/p>\r\n\r\n\r\n\r\n<pre class=\"wp-block-code\"><code>[0,45][412,785]<\/code><\/pre>\r\n\r\n\r\n\r\n<p class=\"wp-block-paragraph\">The resize command was therefore working, but Android was enforcing a larger minimum freeform width at the current 300 DPI density.<\/p>\r\n\r\n\r\n\r\n<p class=\"wp-block-paragraph\">This explained why simply dividing the 720-pixel-wide display into three 240-pixel columns was not going to work at 300 DPI.<\/p>\r\n\r\n\r\n\r\n<h2 class=\"wp-block-heading\">10. Changing the Logical Density to 160 DPI<\/h2>\r\n\r\n\r\n\r\n<p class=\"wp-block-paragraph\">The minimum window width gave me a concrete reason to revisit Android&#8217;s logical display density.<\/p>\r\n\r\n\r\n\r\n<p class=\"wp-block-paragraph\">I changed the logical density to 160 DPI:<\/p>\r\n\r\n\r\n\r\n<pre class=\"wp-block-code\"><code>adb shell wm density 160<\/code><\/pre>\r\n\r\n\r\n\r\n<p class=\"wp-block-paragraph\">I verified the change:<\/p>\r\n\r\n\r\n\r\n<pre class=\"wp-block-code\"><code>adb shell wm density<\/code><\/pre>\r\n\r\n\r\n\r\n<p class=\"wp-block-paragraph\">Android returned:<\/p>\r\n\r\n\r\n\r\n<pre class=\"wp-block-code\"><code>Physical density: 300\r\nOverride density: 160<\/code><\/pre>\r\n\r\n\r\n\r\n<p class=\"wp-block-paragraph\">The physical display had obviously not changed. Android was applying a logical density override.<\/p>\r\n\r\n\r\n\r\n<p class=\"wp-block-paragraph\">I then tried something that Android had effectively prevented at 300 DPI: making the YouTube window only 240 pixels wide.<\/p>\r\n\r\n\r\n\r\n<pre class=\"wp-block-code\"><code>adb shell am task resize 117 0 45 240 785<\/code><\/pre>\r\n\r\n\r\n\r\n<p class=\"wp-block-paragraph\">This time Android accepted the requested rectangle exactly.<\/p>\r\n\r\n\r\n\r\n<pre class=\"wp-block-code\"><code>taskId=117\r\nbounds=[0,45][240,785]\r\nmWindowingMode=freeform\r\nvisible=true\r\n160dpi<\/code><\/pre>\r\n\r\n\r\n\r\n<p class=\"wp-block-paragraph\">scrcpy confirmed the result visually. YouTube was now a narrow freeform window occupying the left side of the screen.<\/p>\r\n<p><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-13360\" src=\"https:\/\/hovatek.com\/blog\/bpyeki\/uploads\/2026\/10\/samsung-a12-density-160-dpi-adb.png\" alt=\"ADB commands setting Samsung Galaxy A12 logical density to 160 DPI and allowing a 240 pixel wide YouTube freeform window\" width=\"1746\" height=\"901\" srcset=\"https:\/\/www.hovatek.com\/blog\/bpyeki\/uploads\/2026\/10\/samsung-a12-density-160-dpi-adb.png 1746w, https:\/\/www.hovatek.com\/blog\/bpyeki\/uploads\/2026\/10\/samsung-a12-density-160-dpi-adb-768x396.png 768w, https:\/\/www.hovatek.com\/blog\/bpyeki\/uploads\/2026\/10\/samsung-a12-density-160-dpi-adb-1536x793.png 1536w\" sizes=\"auto, (max-width: 1746px) 100vw, 1746px\" \/><\/p>\r\n\r\n\r\n\r\n<p class=\"wp-block-paragraph\">This was an important breakthrough. At 300 DPI, Android had expanded my requested narrow window to satisfy its minimum size. At 160 DPI, it accepted the 240-pixel width I needed for three equal columns across the 720-pixel display.<\/p>\r\n\r\n\r\n\r\n<p class=\"wp-block-paragraph\">The density override can later be removed with:<\/p>\r\n\r\n\r\n\r\n<pre class=\"wp-block-code\"><code>adb shell wm density reset<\/code><\/pre>\r\n\r\n\r\n\r\n<h2 class=\"wp-block-heading\">11. Building a Clean Five-Window Grid<\/h2>\r\n\r\n\r\n\r\n<p class=\"wp-block-paragraph\">Now I finally had the pieces I needed to build a proper layout.<\/p>\r\n\r\n\r\n\r\n<p class=\"wp-block-paragraph\">Samsung was keeping five freeform windows visible, so instead of continuing to force a six-window layout that the phone would not display simultaneously, I arranged the five visible applications into a three-over-two grid.<\/p>\r\n\r\n\r\n\r\n<p class=\"wp-block-paragraph\">The target became:<\/p>\r\n\r\n\r\n\r\n<pre class=\"wp-block-preformatted\">+---------+---------+---------+\r\n| YouTube | Chrome  | Gallery |\r\n|  240px  |  240px  |  240px |\r\n+---------+---------+---------+\r\n|      Play Store   | Facebook |\r\n|       360px       |  360px   |\r\n+-------------------+-----------+<\/pre>\r\n\r\n\r\n\r\n<p class=\"wp-block-paragraph\">Before resizing, I checked the task IDs again because some of them had changed as applications were recreated.<\/p>\r\n\r\n\r\n\r\n<p class=\"wp-block-paragraph\">The five visible freeform applications were now:<\/p>\r\n\r\n\r\n\r\n<pre class=\"wp-block-code\"><code>YouTube     taskId=117\r\nChrome      taskId=118\r\nGallery     taskId=121\r\nPlay Store  taskId=120\r\nFacebook    taskId=111<\/code><\/pre>\r\n\r\n\r\n\r\n<p class=\"wp-block-paragraph\">I then issued the five resize commands:<\/p>\r\n\r\n\r\n\r\n<pre class=\"wp-block-code\"><code>adb shell am task resize 117 0 45 240 785\r\nadb shell am task resize 118 240 45 480 785\r\nadb shell am task resize 121 480 45 720 785\r\nadb shell am task resize 120 0 785 360 1525\r\nadb shell am task resize 111 360 785 720 1525<\/code><\/pre>\r\n\r\n\r\n\r\n<p class=\"wp-block-paragraph\">This time Android accepted the requested bounds exactly.<\/p>\r\n<p><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-13361\" src=\"https:\/\/hovatek.com\/blog\/bpyeki\/uploads\/2026\/10\/samsung-a12-five-app-freeform-grid.png\" alt=\"Samsung Galaxy A12 showing five freeform app windows arranged into a three-column top row and two-column bottom row using ADB at 160 DPI\" width=\"1741\" height=\"903\" srcset=\"https:\/\/www.hovatek.com\/blog\/bpyeki\/uploads\/2026\/10\/samsung-a12-five-app-freeform-grid.png 1741w, https:\/\/www.hovatek.com\/blog\/bpyeki\/uploads\/2026\/10\/samsung-a12-five-app-freeform-grid-768x398.png 768w, https:\/\/www.hovatek.com\/blog\/bpyeki\/uploads\/2026\/10\/samsung-a12-five-app-freeform-grid-1536x797.png 1536w\" sizes=\"auto, (max-width: 1741px) 100vw, 1741px\" \/><\/p>\r\n\r\n\r\n\r\n<p class=\"wp-block-paragraph\">The resulting task information showed:<\/p>\r\n\r\n\r\n\r\n<pre class=\"wp-block-code\"><code>YouTube\r\ntaskId=117\r\nbounds=[0,45][240,785]\r\nfreeform\r\nvisible=true\r\n\r\nChrome\r\ntaskId=118\r\nbounds=[240,45][480,785]\r\nfreeform\r\nvisible=true\r\n\r\nGallery\r\ntaskId=121\r\nbounds=[480,45][720,785]\r\nfreeform\r\nvisible=true\r\n\r\nPlay Store\r\ntaskId=120\r\nbounds=[0,785][360,1525]\r\nfreeform\r\nvisible=true\r\n\r\nFacebook\r\ntaskId=111\r\nbounds=[360,785][720,1525]\r\nfreeform\r\nvisible=true<\/code><\/pre>\r\n\r\n\r\n\r\n<p class=\"wp-block-paragraph\">The top row now consisted of three 240-pixel-wide windows covering the entire 720-pixel width, while the bottom row consisted of two 360-pixel-wide windows.<\/p>\r\n\r\n\r\n\r\n<p class=\"wp-block-paragraph\">All five tasks were reported as:<\/p>\r\n\r\n\r\n\r\n<pre class=\"wp-block-code\"><code>mWindowingMode=freeform\r\nmAlwaysOnTop=on\r\nvisible=true<\/code><\/pre>\r\n\r\n\r\n\r\n<p class=\"wp-block-paragraph\">This was the first point in the experiment where I had a clean, deliberate multi-window arrangement created through ADB rather than a collection of overlapping floating windows.<\/p>\r\n\r\n\r\n\r\n<h2 class=\"wp-block-heading\">12. What Happened to the Sixth Window?<\/h2>\r\n\r\n\r\n\r\n<p class=\"wp-block-paragraph\">Settings had not disappeared from Android&#8217;s task system.<\/p>\r\n\r\n\r\n\r\n<p class=\"wp-block-paragraph\">It remained task <code>105<\/code> and was still reported as a freeform task.<\/p>\r\n\r\n\r\n\r\n<p class=\"wp-block-paragraph\">However, after the other five floating windows became visible, Settings showed:<\/p>\r\n\r\n\r\n\r\n<pre class=\"wp-block-code\"><code>taskId=105\r\nmWindowingMode=freeform\r\nmAlwaysOnTop=off\r\nvisible=false<\/code><\/pre>\r\n\r\n\r\n\r\n<p class=\"wp-block-paragraph\">This was an important distinction.<\/p>\r\n\r\n\r\n\r\n<p class=\"wp-block-paragraph\">The Galaxy A12 was not limited to having only five freeform tasks in existence. I had six freeform tasks. What Samsung appeared to limit was the number of freeform windows that could remain visible simultaneously.<\/p>\r\n\r\n\r\n\r\n<p class=\"wp-block-paragraph\">In my test, five were visible while the sixth remained a freeform task with <code>visible=false<\/code>.<\/p>\r\n\r\n\r\n\r\n<h2 class=\"wp-block-heading\">13. Inspecting Samsung&#8217;s Multitasking State<\/h2>\r\n\r\n\r\n\r\n<p class=\"wp-block-paragraph\">To understand what was happening behind the interface, I also inspected Samsung&#8217;s multitasking information:<\/p>\r\n\r\n\r\n\r\n<pre class=\"wp-block-code\"><code>adb shell dumpsys activity multitasking<\/code><\/pre>\r\n\r\n\r\n\r\n<p class=\"wp-block-paragraph\">I continued using:<\/p>\r\n\r\n\r\n\r\n<pre class=\"wp-block-code\"><code>adb shell am stack list<\/code><\/pre>\r\n\r\n\r\n\r\n<p class=\"wp-block-paragraph\">The task information exposed useful properties such as task IDs, bounds, windowing modes, visibility and the always-on-top state.<\/p>\r\n\r\n\r\n\r\n<p class=\"wp-block-paragraph\">A visible floating application could show:<\/p>\r\n\r\n\r\n\r\n<pre class=\"wp-block-code\"><code>mWindowingMode=freeform\r\nmAlwaysOnTop=on\r\nvisible=true<\/code><\/pre>\r\n\r\n\r\n\r\n<p class=\"wp-block-paragraph\">Settings demonstrated the other state:<\/p>\r\n\r\n\r\n\r\n<pre class=\"wp-block-code\"><code>mWindowingMode=freeform\r\nmAlwaysOnTop=off\r\nvisible=false<\/code><\/pre>\r\n\r\n\r\n\r\n<p class=\"wp-block-paragraph\">This helped me distinguish between four things that initially looked similar:<\/p>\r\n\r\n\r\n\r\n<ul class=\"wp-block-list\">\r\n<li>launching an application;<\/li>\r\n<li>Android maintaining a task for that application;<\/li>\r\n<li>the task running in freeform mode; and<\/li>\r\n<li>the freeform window actually being visible.<\/li>\r\n<\/ul>\r\n\r\n\r\n\r\n<p class=\"wp-block-paragraph\">They are not necessarily the same thing.<\/p>\r\n\r\n\r\n\r\n<h2 class=\"wp-block-heading\">14. Looking Inside Samsung&#8217;s Framework<\/h2>\r\n\r\n\r\n\r\n<p class=\"wp-block-paragraph\">The five-visible-window behavior made me curious about where Samsung might be controlling the number of visible freeform windows.<\/p>\r\n\r\n\r\n\r\n<p class=\"wp-block-paragraph\">I created a separate folder for the framework investigation and pulled Samsung&#8217;s <code>services.jar<\/code> directly from the Galaxy A12:<\/p>\r\n\r\n\r\n\r\n<pre class=\"wp-block-code\"><code>mkdir samsung-framework\r\nadb pull \/system\/framework\/services.jar samsung-framework\\services.jar\r\ncd samsung-framework<\/code><\/pre>\r\n\r\n\r\n\r\n<p class=\"wp-block-paragraph\">I confirmed that the file had been copied successfully:<\/p>\r\n\r\n\r\n\r\n<pre class=\"wp-block-code\"><code>dir services.jar<\/code><\/pre>\r\n\r\n\r\n\r\n<p class=\"wp-block-paragraph\">Before extracting anything, I checked which DEX files were stored inside the JAR:<\/p>\r\n\r\n\r\n\r\n<pre class=\"wp-block-code\"><code>tar -tf services.jar | findstr \/i \"classes\"<\/code><\/pre>\r\n\r\n\r\n\r\n<p class=\"wp-block-paragraph\">The archive contained three DEX files:<\/p>\r\n\r\n\r\n\r\n<pre class=\"wp-block-code\"><code>classes.dex\r\nclasses2.dex\r\nclasses3.dex<\/code><\/pre>\r\n\r\n\r\n\r\n<p class=\"wp-block-paragraph\"><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-13396\" src=\"https:\/\/hovatek.com\/blog\/bpyeki\/uploads\/2026\/10\/samsung-services-jar-dex-files-adb.png\" alt=\"ADB pulling Samsung services.jar and verifying classes.dex, classes2.dex and classes3.dex on Galaxy A12\" width=\"1730\" height=\"909\" srcset=\"https:\/\/www.hovatek.com\/blog\/bpyeki\/uploads\/2026\/10\/samsung-services-jar-dex-files-adb.png 1730w, https:\/\/www.hovatek.com\/blog\/bpyeki\/uploads\/2026\/10\/samsung-services-jar-dex-files-adb-768x404.png 768w, https:\/\/www.hovatek.com\/blog\/bpyeki\/uploads\/2026\/10\/samsung-services-jar-dex-files-adb-1536x807.png 1536w\" sizes=\"auto, (max-width: 1730px) 100vw, 1730px\" \/><\/p>\r\n<p>I extracted all three so that I could search them individually:<\/p>\r\n\r\n\r\n\r\n<pre class=\"wp-block-code\"><code>tar -xf services.jar classes.dex classes2.dex classes3.dex<\/code><\/pre>\r\n\r\n\r\n\r\n<p class=\"wp-block-paragraph\">I verified that the files had been extracted:<\/p>\r\n\r\n\r\n\r\n<pre class=\"wp-block-code\"><code>dir classes*.dex<\/code><\/pre>\r\n\r\n\r\n\r\n<p class=\"wp-block-paragraph\">I then searched all three DEX files for <code>FreeformController<\/code>:<\/p>\r\n\r\n\r\n\r\n<pre class=\"wp-block-code\"><code>findstr \/s \/i \/m \"FreeformController\" classes.dex classes2.dex classes3.dex<\/code><\/pre>\r\n\r\n\r\n\r\n<p class=\"wp-block-paragraph\">The search returned:<\/p>\r\n\r\n\r\n\r\n<pre class=\"wp-block-code\"><code>classes3.dex<\/code><\/pre>\r\n\r\n\r\n\r\n<p class=\"wp-block-paragraph\">This told me that the DEX file containing the matching <code>FreeformController<\/code> string was <code>classes3.dex<\/code>. I then searched that file for several names related to Samsung&#8217;s handling of visible freeform windows:<\/p>\r\n\r\n\r\n\r\n<pre class=\"wp-block-code\"><code>findstr \/i \/m \"MAX_FREEFORM_DEFAULT_CNT\" classes3.dex\r\nfindstr \/i \/m \"getMaxVisibleFreeformCntLocked\" classes3.dex\r\nfindstr \/i \/m \"setMaxVisibleFreeformCount\" classes3.dex<\/code><\/pre>\r\n\r\n\r\n\r\n<p class=\"wp-block-paragraph\">Each search returned:<\/p>\r\n\r\n\r\n\r\n<pre class=\"wp-block-code\"><code>classes3.dex<\/code><\/pre>\r\n\r\n\r\n\r\n<p class=\"wp-block-paragraph\">So the strings I confirmed in <code>classes3.dex<\/code> included:<\/p>\r\n\r\n\r\n\r\n<pre class=\"wp-block-code\"><code>FreeformController\r\nMAX_FREEFORM_DEFAULT_CNT\r\ngetMaxVisibleFreeformCntLocked\r\nsetMaxVisibleFreeformCount<\/code><\/pre>\r\n\r\n\r\n\r\n<p class=\"wp-block-paragraph\"><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-13397\" src=\"https:\/\/hovatek.com\/blog\/bpyeki\/uploads\/2026\/10\/samsung-freeformcontroller-classes3-dex.png\" alt=\"Samsung services.jar analysis showing FreeformController, MAX_FREEFORM_DEFAULT_CNT, getMaxVisibleFreeformCntLocked and setMaxVisibleFreeformCount in classes3.dex\" width=\"1714\" height=\"918\" srcset=\"https:\/\/www.hovatek.com\/blog\/bpyeki\/uploads\/2026\/10\/samsung-freeformcontroller-classes3-dex.png 1714w, https:\/\/www.hovatek.com\/blog\/bpyeki\/uploads\/2026\/10\/samsung-freeformcontroller-classes3-dex-768x411.png 768w, https:\/\/www.hovatek.com\/blog\/bpyeki\/uploads\/2026\/10\/samsung-freeformcontroller-classes3-dex-1536x823.png 1536w\" sizes=\"auto, (max-width: 1714px) 100vw, 1714px\" \/><\/p>\r\n<p>Those names were particularly interesting because they lined up with the behavior I had observed on the phone. I had already demonstrated that six freeform tasks could exist while only five remained visible, and Samsung&#8217;s framework contained names explicitly referring to a maximum visible freeform count.<\/p>\r\n\r\n\r\n\r\n<p class=\"wp-block-paragraph\">However, this search did not reveal the actual numeric value of <code>MAX_FREEFORM_DEFAULT_CNT<\/code>. It only confirmed that the string exists in <code>classes3.dex<\/code>. Likewise, finding a name such as <code>setMaxVisibleFreeformCount<\/code> does not prove that it can be called directly through ADB or that changing it would be safe.<\/p>\r\n\r\n\r\n\r\n<p class=\"wp-block-paragraph\">To go further, I would need to decompile or inspect the relevant DEX bytecode and trace how Samsung&#8217;s <code>FreeformController<\/code> uses these values and methods.<\/p>\r\n\r\n\r\n\r\n<h2 class=\"wp-block-heading\">What I Learned From the Experiment<\/h2>\r\n\r\n\r\n\r\n<p class=\"wp-block-paragraph\">The experiment started with a simple question: if the Galaxy A12 could create floating windows through its touchscreen interface, could I control those same windows from ADB?<\/p>\r\n\r\n\r\n\r\n<p class=\"wp-block-paragraph\">The answer turned out to be yes, but getting there involved more than simply running a resize command.<\/p>\r\n\r\n\r\n\r\n<p class=\"wp-block-paragraph\">One of the first things I learned was that launching an application does not mean it is running in freeform mode. The <code>monkey<\/code> commands successfully opened the applications, but most of their tasks remained fullscreen until I resolved their launcher activities and explicitly relaunched them with <code>--windowingMode 5<\/code>.<\/p>\r\n\r\n\r\n\r\n<p class=\"wp-block-paragraph\">I also learned that the current top activity is not necessarily a component ADB can launch directly. Play Store demonstrated this when an internal non-exported activity produced a <code>SecurityException<\/code>.<\/p>\r\n\r\n\r\n\r\n<p class=\"wp-block-paragraph\">YouTube added another complication because its launcher activity contained a dollar sign. Quoting the remote shell command correctly was necessary to prevent <code>$HomeActivity<\/code> from being stripped from the component name.<\/p>\r\n\r\n\r\n\r\n<p class=\"wp-block-paragraph\">The resizing tests then showed that Android could enforce minimum freeform dimensions. At 300 DPI, my request for a narrower YouTube window was expanded to a width of 412 pixels.<\/p>\r\n\r\n\r\n\r\n<p class=\"wp-block-paragraph\">Reducing the logical density to 160 DPI changed that. Android then accepted a 240-pixel-wide freeform window exactly, which made a three-column arrangement possible on the 720-pixel-wide display.<\/p>\r\n\r\n\r\n\r\n<p class=\"wp-block-paragraph\">With the density changed and the current task IDs identified, I was finally able to arrange five visible applications into a clean 3-over-2 grid using nothing but ADB resize commands.<\/p>\r\n\r\n\r\n\r\n<p class=\"wp-block-paragraph\">The biggest limitation remained Samsung&#8217;s handling of the sixth freeform task. Six freeform tasks could exist, but only five remained visible simultaneously during my test. The sixth task stayed in the task list with <code>visible=false<\/code>.<\/p>\r\n\r\n\r\n\r\n<p class=\"wp-block-paragraph\">scrcpy was also invaluable throughout the experiment because it prevented me from confusing a command that returned without an error with a command that actually produced the intended visual result.<\/p>\r\n\r\n\r\n\r\n<p class=\"wp-block-paragraph\">Finally, the changing task IDs reinforced why commands from one session should not simply be copied into another. Chrome, Gallery and Play Store all received different task IDs as I stopped and recreated their tasks.<\/p>\r\n\r\n\r\n\r\n<h2 class=\"wp-block-heading\">Conclusion<\/h2>\r\n\r\n\r\n\r\n<p class=\"wp-block-paragraph\">I did not achieve the six-simultaneously-visible-window TV-style mosaic I originally set out to create, but I got much closer than my early attempts suggested was possible.<\/p>\r\n\r\n\r\n\r\n<p class=\"wp-block-paragraph\">I confirmed that applications on this Samsung Galaxy A12 could be launched into genuine freeform mode from ADB when the correct launcher activity was used. I confirmed that <code>am task resize<\/code> could control the bounds of those windows, and I found that lowering the logical density to 160 DPI allowed Android to accept the narrow 240-pixel windows required for a three-column layout.<\/p>\r\n\r\n\r\n\r\n<p class=\"wp-block-paragraph\">The final working arrangement contained five simultaneously visible freeform applications: YouTube, Chrome and Gallery across the top, with Play Store and Facebook across the bottom.<\/p>\r\n\r\n\r\n\r\n<p class=\"wp-block-paragraph\">A sixth application, Settings, still existed as a freeform task but remained hidden with <code>visible=false<\/code>.<\/p>\r\n\r\n\r\n\r\n<p class=\"wp-block-paragraph\">That means the remaining problem is no longer launching, resizing or positioning the applications. Those parts are now working.<\/p>\r\n\r\n\r\n\r\n<p class=\"wp-block-paragraph\">The remaining obstacle is Samsung&#8217;s apparent five-visible-freeform-window limit.<\/p>\r\n\r\n\r\n\r\n<p class=\"wp-block-paragraph\">The framework investigation has already exposed names such as <code>FreeformController<\/code>, <code>MAX_FREEFORM_DEFAULT_CNT<\/code> and <code>getMaxVisibleFreeformCntLocked<\/code>, but I have not yet traced the code far enough to identify a safe way to change the limit.<\/p>\r\n\r\n\r\n\r\n<p class=\"wp-block-paragraph\">So the original six-window mosaic remains unfinished, but I now know exactly which part of the experiment is still standing in the way.<\/p>\r\n\r\n\r\n\r\n<p class=\"wp-block-paragraph\">If I continue from here, the next experiment will no longer be about arranging Android windows. It will be about finding out exactly how Samsung decides that only five of those freeform windows can remain visible at once.<\/p>\r\n","protected":false},"excerpt":{"rendered":"<p>I already knew that the Samsung Galaxy A12 could open applications in floating windows using the phone&#8217;s touchscreen interface. What I wanted to find out was whether I could control those same floating windows from a computer using ADB. The idea came from the old TV channel-mosaic feature, where several television channels could be displayed [&hellip;]<\/p>\n","protected":false},"author":8,"featured_media":13400,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"site-sidebar-layout":"default","site-content-layout":"","ast-site-content-layout":"default","site-content-style":"default","site-sidebar-style":"default","ast-global-header-display":"","ast-banner-title-visibility":"","ast-main-header-display":"","ast-hfb-above-header-display":"","ast-hfb-below-header-display":"","ast-hfb-mobile-header-display":"","site-post-title":"","ast-breadcrumbs-content":"","ast-featured-img":"","footer-sml-layout":"","ast-disable-related-posts":"","theme-transparent-header-meta":"default","adv-header-id-meta":"","stick-header-meta":"","header-above-stick-meta":"","header-main-stick-meta":"","header-below-stick-meta":"","astra-migrate-meta-layouts":"set","ast-page-background-enabled":"default","ast-page-background-meta":{"desktop":{"background-color":"var(--ast-global-color-4)","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""},"tablet":{"background-color":"","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""},"mobile":{"background-color":"","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""}},"ast-content-background-meta":{"desktop":{"background-color":"var(--ast-global-color-5)","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""},"tablet":{"background-color":"var(--ast-global-color-5)","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""},"mobile":{"background-color":"var(--ast-global-color-5)","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""}},"footnotes":""},"categories":[918,212],"tags":[],"class_list":["post-13389","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-pov","category-tech-tips"],"_links":{"self":[{"href":"https:\/\/www.hovatek.com\/blog\/wp-json\/wp\/v2\/posts\/13389","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.hovatek.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.hovatek.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.hovatek.com\/blog\/wp-json\/wp\/v2\/users\/8"}],"replies":[{"embeddable":true,"href":"https:\/\/www.hovatek.com\/blog\/wp-json\/wp\/v2\/comments?post=13389"}],"version-history":[{"count":7,"href":"https:\/\/www.hovatek.com\/blog\/wp-json\/wp\/v2\/posts\/13389\/revisions"}],"predecessor-version":[{"id":13399,"href":"https:\/\/www.hovatek.com\/blog\/wp-json\/wp\/v2\/posts\/13389\/revisions\/13399"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.hovatek.com\/blog\/wp-json\/wp\/v2\/media\/13400"}],"wp:attachment":[{"href":"https:\/\/www.hovatek.com\/blog\/wp-json\/wp\/v2\/media?parent=13389"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.hovatek.com\/blog\/wp-json\/wp\/v2\/categories?post=13389"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.hovatek.com\/blog\/wp-json\/wp\/v2\/tags?post=13389"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}