81
I Use This!
Activity Not Available

News

Analyzed over 3 years ago.
Posted over 1 year ago by Alberto Mardegan
As you know, I'm trying to get the FM radio to work in Ubuntu Touch, and I basically have it working on the Redmi Note 7 Pro. But then I remembered that the BQ Aquaris E4.5 (which is the first commercial device officially supporting Ubuntu Touch) ... [More] also comes with an FM radio, so I decided to put some effort in getting that to work, too. You might think it's a waste of time, but as a matter of fact this device is built on a Mediatek SoC, and FM radio support is exposed to userspace in a very similar way across all Mediatek devices — so this work should be covering other devices as well. It was relatively easy to get the FM radio to work on this phone: I can now tune to a frequency and see that the RDS data is received, but I cannot get any sound out of the speakers or headphones, which makes the whole radio experience a bit, uhm… suboptimal, let's say. The problem is not new: back in the days when Ubuntu Touch was still supported by Canonical, sturmflut was trying to get the FM radio to work, and he met the same issues (see this and this messages in the mailing list). He also spent some time investigating how the Factory mode works (the FM radio is indeed one of the features that can be tested via the Factory mode, and it does work) and he mentioned that he could get gdb to attach to the factory mode program and could see the various ioctls being executed. Yesterday I tried to follow the same steps, but I failed quite soon: I simply could not connect with adb shell while the device was in factory mode, so no chances of debugging for me. ☹ Out of dispair, I tried just to manually run the program /system/bin/factory inside a Lomiri session and, to my surprise, it overlayed its yellow “Factory Mode” title on the screen — just to immediately quit afterwards. I tried running it with strace, and noticed these lines: open("/sys/class/BOOT/BOOT/boot/boot_mode", O_RDWR|O_LARGEFILE) = 15 read(15, "0\n", 4) = 2 close(15) = 0 writev(5, [{"\3", 1}, {"FTM\0", 4}, {"[FTM UTILS] Unsupported factory "..., 39}], 3) = 44 writev(5, [{"\6", 1}, {"NVRAM\0", 6}, {"[MAIN] Unsupported Factory mode\n"..., 33}], 3) = 40 Of course, the /sys/class/BOOT/BOOT/boot/boot_mode file is read-only, so I couldn't just write 1 into it, but could a bind-mount work? Indeed it did! And after a few attempts, I verified that writing a value of 4 in the boot_mode file made the factory program happy. It was still unusable because it was acting as if the volume down button was being constantly pressed, so the cursor was always moving downwards, but killing the Lomiri session did the trick. In short, these are the steps you need to follow in order to run the Factory Mode from an ordinary boot session: sudo -i # become root echo 4 > /tmp/trick mount -o bind /tmp/trick /sys/class/BOOT/BOOT/boot/boot_mode service lightdm stop # wait a few seconds until this returns unset LD_PRELOAD /system/bin/factory What is more surprising, is that the FM radio test is working even in this environment, and you can actually hear the sounds (for some reason, the FM radio item takes about 40 seconds to initialize when run under these conditions, but it eventually works). At this point, not only I could run gdb (which I didn't), but I could even run the factory program under strace and collect the logs. At the moment of writing this post, I haven't yet examined the logs, so I'm not at all sure that they'll be enough to make audio work (I suspect that the factory mode binary might be playing some tricks that are somehow not replicable in a proper Linux system with Pulseaudio and lots of other services running), but I do have enough information to make at least a few attempts. Stay tuned, and have a Merry Christmas! [Less]
Posted over 1 year ago by Alberto Mardegan
As you know, I'm trying to get the FM radio to work in Ubuntu Touch, and I basically have it working on the Redmi Note 7 Pro. But then I remembered that the BQ Aquaris E4.5 (which is the first commercial device officially supporting Ubuntu Touch) ... [More] also comes with an FM radio, so I decided to put some effort in getting that to work, too. You might think it's a waste of time, but as a matter of fact this device is built on a Mediatek SoC, and FM radio support is exposed to userspace in a very similar way across all Mediatek devices — so this work should be covering other devices as well. It was relatively easy to get the FM radio to work on this phone: I can now tune to a frequency and see that the RDS data is received, but I cannot get any sound out of the speakers or headphones, which makes the whole radio experience a bit, uhm… suboptimal, let's say. The problem is not new: back in the days when Ubuntu Touch was still supported by Canonical, sturmflut was trying to get the FM radio to work, and he met the same issues (see this and this messages in the mailing list). He also spent some time investigating how the Factory mode works (the FM radio is indeed one of the features that can be tested via the Factory mode, and it does work) and he mentioned that he could get gdb to attach to the factory mode program and could see the various ioctls being executed. Yesterday I tried to follow the same steps, but I failed quite soon: I simply could not connect with adb shell while the device was in factory mode, so no chances of debugging for me. ☹ Out of dispair, I tried just to manually run the program /system/bin/factory inside a Lomiri session and, to my surprise, it overlayed its yellow “Factory Mode” title on the screen — just to immediately quit afterwards. I tried running it with strace, and noticed these lines: open("/sys/class/BOOT/BOOT/boot/boot_mode", O_RDWR|O_LARGEFILE) = 15 read(15, "0\n", 4) = 2 close(15) = 0 writev(5, [{"\3", 1}, {"FTM\0", 4}, {"[FTM UTILS] Unsupported factory "..., 39}], 3) = 44 writev(5, [{"\6", 1}, {"NVRAM\0", 6}, {"[MAIN] Unsupported Factory mode\n"..., 33}], 3) = 40 Of course, the /sys/class/BOOT/BOOT/boot/boot_mode file is read-only, so I couldn't just write 1 into it, but could a bind-mount work? Indeed it did! And after a few attempts, I verified that writing a value of 4 in the boot_mode file made the factory program happy. It was still unusable because it was acting as if the volume down button was being constantly pressed, so the cursor was always moving downwards, but killing the Lomiri session did the trick. In short, these are the steps you need to follow in order to run the Factory Mode from an ordinary boot session: sudo -i # become root echo 4 > /tmp/trick mount -o bind /tmp/trick /sys/class/BOOT/BOOT/boot/boot_mode service lightdm stop # wait a few seconds until this returns unset LD_PRELOAD /system/bin/factory What is more surprising, is that the FM radio test is working even in this environment, and you can actually hear the sounds (for some reason, the FM radio item takes about 40 seconds to initialize when run under these conditions, but it eventually works). At this point, not only I could run gdb (which I didn't), but I could even run the factory program under strace and collect the logs. At the moment of writing this post, I haven't yet examined the logs, so I'm not at all sure that they'll be enough to make audio work (I suspect that the factory mode binary might be playing some tricks that are somehow not replicable in a proper Linux system with Pulseaudio and lots of other services running), but I do have enough information to make at least a few attempts. Stay tuned, and have a Merry Christmas!0 0 [Less]
Posted over 1 year ago by Alberto Mardegan
As you know, I'm trying to get the FM radio to work in Ubuntu Touch, and I basically have it working on the Redmi Note 7 Pro. But then I remembered that the BQ Aquaris E4.5 (which is the first commercial device officially supporting Ubuntu Touch) ... [More] also comes with an FM radio, so I decided to put some effort in getting that to work, too. You might think it's a waste of time, but as a matter of fact this device is built on a Mediatek SoC, and FM radio support is exposed to userspace in a very similar way across all Mediatek devices — so this work should be covering other devices as well. It was relatively easy to get the FM radio to work on this phone: I can now tune to a frequency and see that the RDS data is received, but I cannot get any sound out of the speakers or headphones, which makes the whole radio experience a bit, uhm… suboptimal, let's say. The problem is not new: back in the days when Ubuntu Touch was still supported by Canonical, sturmflut was trying to get the FM radio to work, and he met the same issues (see this and this messages in the mailing list). He also spent some time investigating how the Factory mode works (the FM radio is indeed one of the features that can be tested via the Factory mode, and it does work) and he mentioned that he could get gdb to attach to the factory mode program and could see the various ioctls being executed. Yesterday I tried to follow the same steps, but I failed quite soon: I simply could not connect with adb shell while the device was in factory mode, so no chances of debugging for me. ☹ Out of dispair, I tried just to manually run the program /system/bin/factory inside a Lomiri session and, to my surprise, it overlayed its yellow “Factory Mode” title on the screen — just to immediately quit afterwards. I tried running it with strace, and noticed these lines: open("/sys/class/BOOT/BOOT/boot/boot_mode", O_RDWR|O_LARGEFILE) = 15 read(15, "0\n", 4) = 2 close(15) = 0 writev(5, [{"\3", 1}, {"FTM\0", 4}, {"[FTM UTILS] Unsupported factory "..., 39}], 3) = 44 writev(5, [{"\6", 1}, {"NVRAM\0", 6}, {"[MAIN] Unsupported Factory mode\n"..., 33}], 3) = 40 Of course, the /sys/class/BOOT/BOOT/boot/boot_mode file is read-only, so I couldn't just write 1 into it, but could a bind-mount work? Indeed it did! And after a few attempts, I verified that writing a value of 4 in the boot_mode file made the factory program happy. It was still unusable because it was acting as if the volume down button was being constantly pressed, so the cursor was always moving downwards, but killing the Lomiri session did the trick. In short, these are the steps you need to follow in order to run the Factory Mode from an ordinary boot session: sudo -i # become root echo 4 > /tmp/trick mount -o bind /tmp/trick /sys/class/BOOT/BOOT/boot/boot_mode service lightdm stop # wait a few seconds until this returns unset LD_PRELOAD /system/bin/factory What is more surprising, is that the FM radio test is working even in this environment, and you can actually hear the sounds (for some reason, the FM radio item takes about 40 seconds to initialize when run under these conditions, but it eventually works). At this point, not only I could run gdb (which I didn't), but I could even run the factory program under strace and collect the logs. At the moment of writing this post, I haven't yet examined the logs, so I'm not at all sure that they'll be enough to make audio work (I suspect that the factory mode binary might be playing some tricks that are somehow not replicable in a proper Linux system with Pulseaudio and lots of other services running), but I do have enough information to make at least a few attempts. Stay tuned, and have a Merry Christmas! 0 0 [Less]
Posted over 1 year ago by Philip Van Hoof
We are a few years further. A few years in which we all tried to make a difference. I’m incredibly proud of my achievement of QTBUG-61928. At the time I thought I could never convince the Qt development team of changing their APIs. They did and ... [More] today in Qt6 it’s all very much part of the package. I want to thank Thiago and others. But I also think it’s a team effort. It might not be because of just me. But I still feel a little bit proud of having pushed this team just enough to make the changes. I am now at a new Qt bug report. This time it’s about int64_t. I think that QModelIndex should be completely supporting it. Again, I think a lot. And I have a lot of opinions. But I anyway filed QTBUG-99312 for this. 0 0 [Less]
Posted over 1 year ago by Alberto Mardegan
I recently realized that my Xiaomi Redmi Note 7 Pro, on which I installed Ubuntu Touch not so long ago, has a working FM radio. One of the many psychological bugs of mine is the irrational urge I feel of having my hardware, no matter whether I use ... [More] it or not, supported by Linux. So, the fact that I never listen to the radio is unfortunately not a reason to dissuade me from wasting time on getting the FM radio working in Ubuntu Touch. This post is a quick summary of my investigation, which should serve as a note keeper for when I'll actually get to implement the feature. The Android story It was a bit surprising to find out that Android does not offer an API to use the FM radio, meaning that we cannot simply expose an API via libhybris. Every manufacturer is therefore choosing their own API, and Android applications are most often developed for a specific chipset family, or need to carry the code to support all the various devices. For example, I found the RFM Radio Android application which supports a few Qualcomm Snapdragon processors, for which the FM radio functionality is exposed by a kernel driver via the V4L API. This means that the FM radio is probably working out of the box with QtMultimedia's QRadioTuner. Unfortunately the Note 7 Pro uses a newer Snapdragon, and even after some days of investigations I couldn't find out how the radio driver communicates to the userspace; but more on this below. Other chipsets offer other APIs, and I was glad to find that someone already wrote a Ubuntu Touch FM radio application for the Volla phone, which has a Mediatek board. Anyway, the lack of a unified FM radio API is probably the reason why most of the so-called “FM radio” applications on Android are not really using the FM radio but rather streaming audio from the internet. The FM radio in the Note 7 Pro Before I start talking about a phone that no one cares about, let me say that what I'm going to write applies to several other Snapdragon chipsets and could be relevant to other phones. For one, the Redmi Note 9 Pro uses the very same bluetooth chipset as the Note 7 Pro (and in case you are wondering why I mentioned bluetooth, it's because the FM radio functionality is delivered by the same BT chip), so all what I'm going to write here is also relevant for that phone. In order to figure out how the radio worked on this device, I took the drastic decision to reflash the stock Android (well, MIUI), started the preinstalled FM radio application, and meanwhile looked at the logcat messages (I'm not sure if this is needed, but before doing so I went to the “Developer options” in the system settings and set the debugging level to the maximum). Among a lot of noise, this showed me lines like these: I android_hardware_fm: Opened fm_helium.so shared object library successfully I android_hardware_fm: Obtaining handle: 'FM_HELIUM_LIB_INTERFACE' to the shared object library... D FmReceiverJNI: init native called D android_hardware_fm: BT soc is cherokee I android_hardware_fm: Init native called I android_hardware_fm: Initializing the FM HAL module & registering the JNI callback functions... D radio_helium: ++hal_init D fm_hci : ++fm_hci_init I fm_hci : hci_initialize Well, even without knowing nothing about all what these lines meant, I had something I could search the internet for. So I found the Qualcomm FM code in CodeAurora, and search for the code relative to my Snapdragon 675 (aka sm6150). I quickly gave up on trying to make some sense out of the git tag naming in that repository, and just tried to search for a tag which could be referring to my device. I found one, and started browsing its source tree. It turns out that Qualcomm provides a Java package which applications can use, and which internally dlopen()s the fm_helium.so library, which in turn depends on the libfm_hci.so library. I had a quick look at the source code of these libraries, which are also present in the repository, but decided that I would have had more chances of success if I just tried to follow the JNI code, and in particular the android_hardware_fm.cpp file. I'm not sure why this code is not using the C structure types defined in the headers provided by the helium library, and instead redefines all the constants and accesses the character buffers by offsets — it might be just for historical reasons — but in any case I decided to follow along. The fm-bridge program Since we have a rather net separation between the Ubuntu Touch and the Android worlds (the Android services are running inside an LXC container, with all their Android libs and dependencies), one should not attempt to write an Ubuntu process that loads the Android libraries, because the libc used in Android is different, so things are likely not to work. But we can have Ubuntu and Android processes communicate over a socket or other kind of IPC; so, what I decided to go for, is writing a small C program that will live in the Android side, it will talk to the FM radio (via helium_fm), and accept commands / give replies via its stdin / stdout. I unimaginatively called it “fm-bridge”, and you can look at its horrible code here. Really, I just said it was terrible, so why did you look at it? I definitely need to rewrite it from scratch, possibly using the helium headers, but as a proof of concept this also works. Then I carefully examined the logcat output while using the MIUI FM radio application in Android, and figured out what was the command sequence I had to input into fm-bridge's standard input in order to have it tune onto a given frequency. I'm publishing the commands here too, should I ever lose my notes: enableSlimbus 1 setControl 0x8000004 1 enableSoftMute 1 setControl 0x8000029 0 setControl 0x800000c 1 setControl 0x800000d 1 setControl 0x800000e 1 setControl 0x800002b 0 setControl 0x8000007 4 setControl 0x8000006 0x40 setControl 0x8000006 0x40 setControl 0x8000011 0 setControl 0x800000f 1 getControl 0x8000010 setControl 0x8000010 0xef setControl 0x800000f 1 setControl 0x800001b 1 setControl 0x8000012 0 setFreq 89300 setMonoStereo 1 I'm sure that not all of them are needed, but I'll figure out the optimal sequence later. In order to use this program on Ubuntu Touch, I had to alter the vendor partition to add this program, but also the fm_helium.so and libfm_hci.so libraries (more on that below). When feeding the above commands to the fm-bridge in Ubuntu, I saw that I was getting a logcat output similar to the one from Android, which was mildly comforting. No sound was comint out of the speaker or out of the earplugs, but I was hardly expecting it all to work at the first try. And I got convinced that the FM tuner was indeed working, because typing the command “startSearch 1” made a new frequency appear in the logs, proving that the tuner had found another station and tuned onto it. Getting the sound out This was actually the easiest of the steps, thanks to the Ubuntu Touch FM radio application we have for the Volla: its source code mentions a few pulseaudio commands that worked perfectly in the Note 7 Pro too, despite the fact that the underlying chipset is totally different. This should not be as surprising as it might sound like, given that Android has a common audio API. Just for my future reference, the commands are these: pacmd set-source-port 1 input-fm_tuner pactl load-module module-loopback source=1 sink=0 Ta-daaa! The radio was now playing from the phone loudspeakers! It was indeed quite loud, and the volume buttons did not seem to have any effect on it, but the volume can be controlled with pulseaudio: pactl set-source-volume 1 50% Of course, if we ever manage to make this into an Ubuntu Touch feature, we'll have to find a way to make the volume respond to the volume buttons. Addind the needed files to the vendor partition The simplest approach (and the one I took initially) is that of downloading the vendor.img into your PC, loop-mounting it, adding the fm_helium.so, libfm_hci.so and fm-bridge files to it and then umount the partition and reflash it (remembering to converting it from/to a sparse image before downloading/uploading it). This approach works flawlessly, but I'm wondering if one might incur into issues if the version of the NDK used to compile fm-bridge is different from the one that was used to compile the other vendor binaries, so I decided to give it a try to build the whole vendor partition myself. This turned out to be a non trivial process, because I was using the Halium tree to build the vendor image, and not the LineageOS which was used to build the vendor image for my device: I could make an image, but it took some time before I figured out which were the needed packages that somehow got lost because of the Halium changes and that had to be added to the Makefile. To help my weak memory, I expanded the README file in the violet port with the steps needed in order to build the vendor image. A system service for the FM radio While it could be possible for Ubuntu Touch applications to directly access the FM radio device in the same way that Android applications do, this is suboptimal for a few reasons. Even if we provided a shared library to deal with the various radio chipset implementations, the application would either need to be unconfined, or we'd had to provide an ever-changing AppArmor profile that peeks new holes every time that a new device implementation is added (and what if this implemenation uses a generic kernel device, which could be used for other goals too?) and in any case we'd have to make this policy restricted, since the RDS data provided by the radio stations would reveal the user location (well, the city at least) to the application. Not to talk about concurrent access to the radio device if two applications attempt to use it. Therefore, my proposition (and what I'll implement, if I'll live long enough or if someone doesn't beat me to it) is to have a system service deal with the various hardware differences and expose a D-Bus API that will be hooked up as a QRadioTunerControl plugin, so that Qt applications will be able to just use the QtMultimedia APIs to access the radio. The service would also need to talk to the trust-store, to let the user decide whether the application should really be granted access to the FM receiver (and when using the turst-store, this decision is remembered, and revocable from the System Settings's Security panel). Of course we'll also need to add a fm-radio AppArmor policy to let applications use this service. [Less]
Posted over 1 year ago by Alberto Mardegan
I recently realized that my Xiaomi Redmi Note 7 Pro, on which I installed Ubuntu Touch not so long ago, has a working FM radio. One of the many psychological bugs of mine is the irrational urge I feel of having my hardware, no matter whether I use ... [More] it or not, supported by Linux. So, the fact that I never listen to the radio is unfortunately not a reason to dissuade me from wasting time on getting the FM radio working in Ubuntu Touch. This post is a quick summary of my investigation, which should serve as a note keeper for when I'll actually get to implement the feature. The Android story It was a bit surprising to find out that Android does not offer an API to use the FM radio, meaning that we cannot simply expose an API via libhybris. Every manufacturer is therefore choosing their own API, and Android applications are most often developed for a specific chipset family, or need to carry the code to support all the various devices. For example, I found the RFM Radio Android application which supports a few Qualcomm Snapdragon processors, for which the FM radio functionality is exposed by a kernel driver via the V4L API. This means that the FM radio is probably working out of the box with QtMultimedia's QRadioTuner. Unfortunately the Note 7 Pro uses a newer Snapdragon, and even after some days of investigations I couldn't find out how the radio driver communicates to the userspace; but more on this below. Other chipsets offer other APIs, and I was glad to find that someone already wrote a Ubuntu Touch FM radio application for the Volla phone, which has a Mediatek board. Anyway, the lack of a unified FM radio API is probably the reason why most of the so-called “FM radio” applications on Android are not really using the FM radio but rather streaming audio from the internet. The FM radio in the Note 7 Pro Before I start talking about a phone that no one cares about, let me say that what I'm going to write applies to several other Snapdragon chipsets and could be relevant to other phones. For one, the Redmi Note 9 Pro uses the very same bluetooth chipset as the Note 7 Pro (and in case you are wondering why I mentioned bluetooth, it's because the FM radio functionality is delivered by the same BT chip), so all what I'm going to write here is also relevant for that phone. In order to figure out how the radio worked on this device, I took the drastic decision to reflash the stock Android (well, MIUI), started the preinstalled FM radio application, and meanwhile looked at the logcat messages (I'm not sure if this is needed, but before doing so I went to the “Developer options” in the system settings and set the debugging level to the maximum). Among a lot of noise, this showed me lines like these: I android_hardware_fm: Opened fm_helium.so shared object library successfully I android_hardware_fm: Obtaining handle: 'FM_HELIUM_LIB_INTERFACE' to the shared object library... D FmReceiverJNI: init native called D android_hardware_fm: BT soc is cherokee I android_hardware_fm: Init native called I android_hardware_fm: Initializing the FM HAL module & registering the JNI callback functions... D radio_helium: ++hal_init D fm_hci : ++fm_hci_init I fm_hci : hci_initialize Well, even without knowing nothing about all what these lines meant, I had something I could search the internet for. So I found the Qualcomm FM code in CodeAurora, and search for the code relative to my Snapdragon 675 (aka sm6150). I quickly gave up on trying to make some sense out of the git tag naming in that repository, and just tried to search for a tag which could be referring to my device. I found one, and started browsing its source tree. It turns out that Qualcomm provides a Java package which applications can use, and which internally dlopen()s the fm_helium.so library, which in turn depends on the libfm_hci.so library. I had a quick look at the source code of these libraries, which are also present in the repository, but decided that I would have had more chances of success if I just tried to follow the JNI code, and in particular the android_hardware_fm.cpp file. I'm not sure why this code is not using the C structure types defined in the headers provided by the helium library, and instead redefines all the constants and accesses the character buffers by offsets — it might be just for historical reasons — but in any case I decided to follow along. The fm-bridge program Since we have a rather net separation between the Ubuntu Touch and the Android worlds (the Android services are running inside an LXC container, with all their Android libs and dependencies), one should not attempt to write an Ubuntu process that loads the Android libraries, because the libc used in Android is different, so things are likely not to work. But we can have Ubuntu and Android processes communicate over a socket or other kind of IPC; so, what I decided to go for, is writing a small C program that will live in the Android side, it will talk to the FM radio (via helium_fm), and accept commands / give replies via its stdin / stdout. I unimaginatively called it “fm-bridge”, and you can look at its horrible code here. Really, I just said it was terrible, so why did you look at it? I definitely need to rewrite it from scratch, possibly using the helium headers, but as a proof of concept this also works. Then I carefully examined the logcat output while using the MIUI FM radio application in Android, and figured out what was the command sequence I had to input into fm-bridge's standard input in order to have it tune onto a given frequency. I'm publishing the commands here too, should I ever lose my notes: enableSlimbus 1 setControl 0x8000004 1 enableSoftMute 1 setControl 0x8000029 0 setControl 0x800000c 1 setControl 0x800000d 1 setControl 0x800000e 1 setControl 0x800002b 0 setControl 0x8000007 4 setControl 0x8000006 0x40 setControl 0x8000006 0x40 setControl 0x8000011 0 setControl 0x800000f 1 getControl 0x8000010 setControl 0x8000010 0xef setControl 0x800000f 1 setControl 0x800001b 1 setControl 0x8000012 0 setFreq 89300 setMonoStereo 1 I'm sure that not all of them are needed, but I'll figure out the optimal sequence later. In order to use this program on Ubuntu Touch, I had to alter the vendor partition to add this program, but also the fm_helium.so and libfm_hci.so libraries (more on that below). When feeding the above commands to the fm-bridge in Ubuntu, I saw that I was getting a logcat output similar to the one from Android, which was mildly comforting. No sound was comint out of the speaker or out of the earplugs, but I was hardly expecting it all to work at the first try. And I got convinced that the FM tuner was indeed working, because typing the command “startSearch 1” made a new frequency appear in the logs, proving that the tuner had found another station and tuned onto it. Getting the sound out This was actually the easiest of the steps, thanks to the Ubuntu Touch FM radio application we have for the Volla: its source code mentions a few pulseaudio commands that worked perfectly in the Note 7 Pro too, despite the fact that the underlying chipset is totally different. This should not be as surprising as it might sound like, given that Android has a common audio API. Just for my future reference, the commands are these: pacmd set-source-port 1 input-fm_tuner pactl load-module module-loopback source=1 sink=0 Ta-daaa! The radio was now playing from the phone loudspeakers! It was indeed quite loud, and the volume buttons did not seem to have any effect on it, but the volume can be controlled with pulseaudio: pactl set-source-volume 1 50% Of course, if we ever manage to make this into an Ubuntu Touch feature, we'll have to find a way to make the volume respond to the volume buttons. Addind the needed files to the vendor partition The simplest approach (and the one I took initially) is that of downloading the vendor.img into your PC, loop-mounting it, adding the fm_helium.so, libfm_hci.so and fm-bridge files to it and then umount the partition and reflash it (remembering to converting it from/to a sparse image before downloading/uploading it). This approach works flawlessly, but I'm wondering if one might incur into issues if the version of the NDK used to compile fm-bridge is different from the one that was used to compile the other vendor binaries, so I decided to give it a try to build the whole vendor partition myself. This turned out to be a non trivial process, because I was using the Halium tree to build the vendor image, and not the LineageOS which was used to build the vendor image for my device: I could make an image, but it took some time before I figured out which were the needed packages that somehow got lost because of the Halium changes and that had to be added to the Makefile. To help my weak memory, I expanded the README file in the violet port with the steps needed in order to build the vendor image. A system service for the FM radio While it could be possible for Ubuntu Touch applications to directly access the FM radio device in the same way that Android applications do, this is suboptimal for a few reasons. Even if we provided a shared library to deal with the various radio chipset implementations, the application would either need to be unconfined, or we'd had to provide an ever-changing AppArmor profile that peeks new holes every time that a new device implementation is added (and what if this implemenation uses a generic kernel device, which could be used for other goals too?) and in any case we'd have to make this policy restricted, since the RDS data provided by the radio stations would reveal the user location (well, the city at least) to the application. Not to talk about concurrent access to the radio device if two applications attempt to use it. Therefore, my proposition (and what I'll implement, if I'll live long enough or if someone doesn't beat me to it) is to have a system service deal with the various hardware differences and expose a D-Bus API that will be hooked up as a QRadioTunerControl plugin, so that Qt applications will be able to just use the QtMultimedia APIs to access the radio. The service would also need to talk to the trust-store, to let the user decide whether the application should really be granted access to the FM receiver (and when using the turst-store, this decision is remembered, and revocable from the System Settings's Security panel). Of course we'll also need to add a fm-radio AppArmor policy to let applications use this service. 0 0 [Less]
Posted over 1 year ago by Alberto Mardegan
I recently realized that my Xiaomi Redmi Note 7 Pro, on which I installed Ubuntu Touch not so long ago, has a working FM radio. One of the many psychological bugs of mine is the irrational urge I feel of having my hardware, no matter whether I use ... [More] it or not, supported by Linux. So, the fact that I never listen to the radio is unfortunately not a reason to dissuade me from wasting time on getting the FM radio working in Ubuntu Touch. This post is a quick summary of my investigation, which should serve as a note keeper for when I'll actually get to implement the feature. The Android story It was a bit surprising to find out that Android does not offer an API to use the FM radio, meaning that we cannot simply expose an API via libhybris. Every manufacturer is therefore choosing their own API, and Android applications are most often developed for a specific chipset family, or need to carry the code to support all the various devices. For example, I found the RFM Radio Android application which supports a few Qualcomm Snapdragon processors, for which the FM radio functionality is exposed by a kernel driver via the V4L API. This means that the FM radio is probably working out of the box with QtMultimedia's QRadioTuner. Unfortunately the Note 7 Pro uses a newer Snapdragon, and even after some days of investigations I couldn't find out how the radio driver communicates to the userspace; but more on this below. Other chipsets offer other APIs, and I was glad to find that someone already wrote a Ubuntu Touch FM radio application for the Volla phone, which has a Mediatek board. Anyway, the lack of a unified FM radio API is probably the reason why most of the so-called “FM radio” applications on Android are not really using the FM radio but rather streaming audio from the internet. The FM radio in the Note 7 Pro Before I start talking about a phone that no one cares about, let me say that what I'm going to write applies to several other Snapdragon chipsets and could be relevant to other phones. For one, the Redmi Note 9 Pro uses the very same bluetooth chipset as the Note 7 Pro (and in case you are wondering why I mentioned bluetooth, it's because the FM radio functionality is delivered by the same BT chip), so all what I'm going to write here is also relevant for that phone. In order to figure out how the radio worked on this device, I took the drastic decision to reflash the stock Android (well, MIUI), started the preinstalled FM radio application, and meanwhile looked at the logcat messages (I'm not sure if this is needed, but before doing so I went to the “Developer options” in the system settings and set the debugging level to the maximum). Among a lot of noise, this showed me lines like these: I android_hardware_fm: Opened fm_helium.so shared object library successfully I android_hardware_fm: Obtaining handle: 'FM_HELIUM_LIB_INTERFACE' to the shared object library... D FmReceiverJNI: init native called D android_hardware_fm: BT soc is cherokee I android_hardware_fm: Init native called I android_hardware_fm: Initializing the FM HAL module & registering the JNI callback functions... D radio_helium: ++hal_init D fm_hci : ++fm_hci_init I fm_hci : hci_initialize Well, even without knowing nothing about all what these lines meant, I had something I could search the internet for. So I found the Qualcomm FM code in CodeAurora, and search for the code relative to my Snapdragon 675 (aka sm6150). I quickly gave up on trying to make some sense out of the git tag naming in that repository, and just tried to search for a tag which could be referring to my device. I found one, and started browsing its source tree. It turns out that Qualcomm provides a Java package which applications can use, and which internally dlopen()s the fm_helium.so library, which in turn depends on the libfm_hci.so library. I had a quick look at the source code of these libraries, which are also present in the repository, but decided that I would have had more chances of success if I just tried to follow the JNI code, and in particular the android_hardware_fm.cpp file. I'm not sure why this code is not using the C structure types defined in the headers provided by the helium library, and instead redefines all the constants and accesses the character buffers by offsets — it might be just for historical reasons — but in any case I decided to follow along. The fm-bridge program Since we have a rather net separation between the Ubuntu Touch and the Android worlds (the Android services are running inside an LXC container, with all their Android libs and dependencies), one should not attempt to write an Ubuntu process that loads the Android libraries, because the libc used in Android is different, so things are likely not to work. But we can have Ubuntu and Android processes communicate over a socket or other kind of IPC; so, what I decided to go for, is writing a small C program that will live in the Android side, it will talk to the FM radio (via helium_fm), and accept commands / give replies via its stdin / stdout. I unimaginatively called it “fm-bridge”, and you can look at its horrible code here. Really, I just said it was terrible, so why did you look at it? I definitely need to rewrite it from scratch, possibly using the helium headers, but as a proof of concept this also works. Then I carefully examined the logcat output while using the MIUI FM radio application in Android, and figured out what was the command sequence I had to input into fm-bridge's standard input in order to have it tune onto a given frequency. I'm publishing the commands here too, should I ever lose my notes: enableSlimbus 1 setControl 0x8000004 1 enableSoftMute 1 setControl 0x8000029 0 setControl 0x800000c 1 setControl 0x800000d 1 setControl 0x800000e 1 setControl 0x800002b 0 setControl 0x8000007 4 setControl 0x8000006 0x40 setControl 0x8000006 0x40 setControl 0x8000011 0 setControl 0x800000f 1 getControl 0x8000010 setControl 0x8000010 0xef setControl 0x800000f 1 setControl 0x800001b 1 setControl 0x8000012 0 setFreq 89300 setMonoStereo 1 I'm sure that not all of them are needed, but I'll figure out the optimal sequence later. In order to use this program on Ubuntu Touch, I had to alter the vendor partition to add this program, but also the fm_helium.so and libfm_hci.so libraries (more on that below). When feeding the above commands to the fm-bridge in Ubuntu, I saw that I was getting a logcat output similar to the one from Android, which was mildly comforting. No sound was comint out of the speaker or out of the earplugs, but I was hardly expecting it all to work at the first try. And I got convinced that the FM tuner was indeed working, because typing the command “startSearch 1” made a new frequency appear in the logs, proving that the tuner had found another station and tuned onto it. Getting the sound out This was actually the easiest of the steps, thanks to the Ubuntu Touch FM radio application we have for the Volla: its source code mentions a few pulseaudio commands that worked perfectly in the Note 7 Pro too, despite the fact that the underlying chipset is totally different. This should not be as surprising as it might sound like, given that Android has a common audio API. Just for my future reference, the commands are these: pacmd set-source-port 1 input-fm_tuner pactl load-module module-loopback source=1 sink=0 Ta-daaa! The radio was now playing from the phone loudspeakers! It was indeed quite loud, and the volume buttons did not seem to have any effect on it, but the volume can be controlled with pulseaudio: pactl set-source-volume 1 50% Of course, if we ever manage to make this into an Ubuntu Touch feature, we'll have to find a way to make the volume respond to the volume buttons. Addind the needed files to the vendor partition The simplest approach (and the one I took initially) is that of downloading the vendor.img into your PC, loop-mounting it, adding the fm_helium.so, libfm_hci.so and fm-bridge files to it and then umount the partition and reflash it (remembering to converting it from/to a sparse image before downloading/uploading it). This approach works flawlessly, but I'm wondering if one might incur into issues if the version of the NDK used to compile fm-bridge is different from the one that was used to compile the other vendor binaries, so I decided to give it a try to build the whole vendor partition myself. This turned out to be a non trivial process, because I was using the Halium tree to build the vendor image, and not the LineageOS which was used to build the vendor image for my device: I could make an image, but it took some time before I figured out which were the needed packages that somehow got lost because of the Halium changes and that had to be added to the Makefile. To help my weak memory, I expanded the README file in the violet port with the steps needed in order to build the vendor image. A system service for the FM radio While it could be possible for Ubuntu Touch applications to directly access the FM radio device in the same way that Android applications do, this is suboptimal for a few reasons. Even if we provided a shared library to deal with the various radio chipset implementations, the application would either need to be unconfined, or we'd had to provide an ever-changing AppArmor profile that peeks new holes every time that a new device implementation is added (and what if this implemenation uses a generic kernel device, which could be used for other goals too?) and in any case we'd have to make this policy restricted, since the RDS data provided by the radio stations would reveal the user location (well, the city at least) to the application. Not to talk about concurrent access to the radio device if two applications attempt to use it. Therefore, my proposition (and what I'll implement, if I'll live long enough or if someone doesn't beat me to it) is to have a system service deal with the various hardware differences and expose a D-Bus API that will be hooked up as a QRadioTunerControl plugin, so that Qt applications will be able to just use the QtMultimedia APIs to access the radio. The service would also need to talk to the trust-store, to let the user decide whether the application should really be granted access to the FM receiver (and when using the turst-store, this decision is remembered, and revocable from the System Settings's Security panel). Of course we'll also need to add a fm-radio AppArmor policy to let applications use this service.0 0 [Less]
Posted over 1 year ago by Pavel Rojtberg
This post will be for those of you that care about privacy – i.e. if you want that information about you is exclusively under your control.In that context not only Google is to blame, but actually most of the cloud services we know and use today. ... [More] Still Google will serve us as a nice placeholder as it is the market-leader when it comes to providing free services in exchange for your user-profile that Google in turn uses to sell target advertising. Even if you are fine with that, Google is also infamous for killing services – which might hit the one you rely on eventually. As the world is moving mobile-first, a prerequisite for replacing a service is that we can easily integrate the replacement with an Android device.Some might wonder why I chose Android here, given that it is made by Google. See, the problem is not who makes a service/ device, but who controls it. And with Android the main leverage for Google is bundling its services. If you take them away, the device itself is fully under your control – in contrast to Apple/ iOS. Now, that we set the stage, lets start with: Nextcloud At the heart of our efforts will be Nextcloud. This started as an open-source alternative to Dropbox/ Google Drive, but is nowadays grown into a platform for a plethora of different services.The main selling-point is that you can just install Nextcloud on your own machine – ensuring that your data stays private. The software being Open-Source also means that it is not under control of a single corporation – in fact Nextcloud was forked from its predecessor Owncloud after a corporation tried to put the screws on its users. Note pharmrx.online , that if you are serious about this, you will need to invest around 500€ to get a machine for hosting that is decently fail-safe. If you rather want to be cheap, you can also just use a RaspberryPi to get away with less than half of that amount. For inspiration, you can take a look on the built I use or on the list of commercial nextcloud device providers. Files & Photos By using the Nextcloud Android App, you can directly replace Google Drive/ Dropbox as this is the core functionality of Nextcloud. Additionally, the App allows you to automatically back-up your Photos/ Videos and free the local storage so you can stop using Google Photos too. Contacts & Calendar Nextcloud also supports Contacts and Calendar out of the box. To integrate them with into your Android Device there is the DAVx5 app. This app will function as an additional data provider, so you can just continue using the stock Google Contacts and Calendar apps. Those will, however, stop sending any data to Google. This is especially useful, if you run a small-business and must ensure that your customer data is private according to the CCPA/ GDPR. Nextcloud News An often overlooked part of your privacy is Google News (also part of Google Now). Each time you view an article there, Google can mine your interests and political views – similar to what Facebook does. And by now you should know where these things can lead. Another drawback here is that the Google Algorithm will create a bubble for you by only showing content coherent with your current world-view.I still prefer to manually choose the news sources – to create that bubble myself. To do that, one usual subscribes some Web-feeds using a Feed aggregator like the Feedly service – similar to what Google Reader used to offer, before being killed by Google. The go-to app here is Nextcloud News combined with the Android App for a pleasant mobile usage. Music Most of you are probably just stream music via Spotify/ Youtube Music, but keep in mind that these services merely rent the songs and as such they can arbitrarily disappear from your library. Therefore, I like to have my own copy of the song. Unfortunately it is very inconvenient to juggle mp3s around for getting the music to various devices. Google Play Music used to offer best of both worlds for me, where you could upload your own music files and manage your playlists in one place. Additionally, you could make the music available offline by pinning individual playlists on your device.Unfortunately, that concept did not allow Google to arbitrarily inject ads into my music stream and therefore the service got killed as well. Nextcloud Music to the rescue! This app picks up your music library via Nextcloud files and allows to stream that via the Browser or the Subsonic API.This is where the DSub Android Player takes over. As with Play Music, you can either stream the library or pin individual songs/ playlists for offline use. Note: untick the “Authorization Basic headers” box when setting-up Nextcloud Music. Other If you clicked on the links above, you probably noticed the F-Droid alternative app store for Android.Getting your apps there ensures that you are using verified packages and open-source software. You can easily use it alongside with the Play Store. If that is too inconvenient for you, all of the above apps are also available via the Play Store. Finally, there is the web-browser. If you do not log in with your Google Account, using Chrome is mostly safe. However, I suggest switching to Firefox. See the my original article on that topic for details. In short; the main reason is the availability of extensions. Those allow you to block ads on the mobile web too and use Youtube in the backround. Header Image: Digital Chains by stanjourdan (CC-BY-SA-2.0) 0 0 [Less]
Posted over 1 year ago by Pavel Rojtberg
This post will be for those of you that care about privacy – i.e. if you want that information about you is exclusively under your control.In that context not only Google is to blame, but actually most of the cloud services we know and use today. ... [More] Still Google will serve us as a nice placeholder as it is the market-leader when it comes to providing free services in exchange for your user-profile that Google in turn uses to sell target advertising. Even if you are fine with that, Google is also infamous for killing services – which might hit the one you rely on eventually. As the world is moving mobile-first, a prerequisite for replacing a service is that we can easily integrate the replacement with an Android device.Some might wonder why I chose Android here, given that it is made by Google. See, the problem is not who makes a service/ device, but who controls it. And with Android the main leverage for Google is bundling its services. If you take them away, the device itself is fully under your control – in contrast to Apple/ iOS. Now, that we set the stage, lets start with: Nextcloud At the heart of our efforts will be Nextcloud. This started as an open-source alternative to Dropbox/ Google Drive, but is nowadays grown into a platform for a plethora of different services.The main selling-point is that you can just install Nextcloud on your own machine – ensuring that your data stays private. The software being Open-Source also means that it is not under control of a single corporation – in fact Nextcloud was forked from its predecessor Owncloud after a corporation tried to put the screws on its users. Note, that if you are serious about this, you will need to invest around 500€ to get a machine for hosting that is decently fail-safe. If you rather want to be cheap, you can also just use a RaspberryPi to get away with less than half of that amount. For inspiration, you can take a look on the built I use or on the list of commercial nextcloud device providers. Files & Photos By using the Nextcloud Android App, you can directly replace Google Drive/ Dropbox as this is the core functionality of Nextcloud. Additionally, the App allows you to automatically back-up your Photos/ Videos and free the local storage so you can stop using Google Photos too. Contacts & Calendar Nextcloud also supports Contacts and Calendar out of the box. To integrate them with into your Android Device there is the DAVx5 app. This app will function as an additional data provider, so you can just continue using the stock Google Contacts and Calendar apps. Those will, however, stop sending any data to Google. This is especially useful, if you run a small-business and must ensure that your customer data is private according to the CCPA/ GDPR. Nextcloud News An often overlooked part of your privacy is Google News (also part of Google Now). Each time you view an article there, Google can mine your interests and political views – similar to what Facebook does. And by now you should know where these things can lead. Another drawback here is that the Google Algorithm will create a bubble for you by only showing content coherent with your current world-view.I still prefer to manually choose the news sources – to create that bubble myself. To do that, one usual subscribes some Web-feeds using a Feed aggregator like the Feedly service – similar to what Google Reader used to offer, before being killed by Google. The go-to app here is Nextcloud News combined with the Android App for a pleasant mobile usage. Music Most of you are probably just stream music via Spotify/ Youtube Music, but keep in mind that these services merely rent the songs and as such they can arbitrarily disappear from your library. Therefore, I like to have my own copy of the song. Unfortunately it is very inconvenient to juggle mp3s around for getting the music to various devices. Google Play Music used to offer best of both worlds for me, where you could upload your own music files and manage your playlists in one place. Additionally, you could make the music available offline by pinning individual playlists on your device.Unfortunately, that concept did not allow Google to arbitrarily inject ads into my music stream and therefore the service got killed as well. Nextcloud Music to the rescue! This app picks up your music library via Nextcloud files and allows to stream that via the Browser or the Subsonic API.This is where the DSub Android Player takes over. As with Play Music, you can either stream the library or pin individual songs/ playlists for offline use. Note: untick the “Authorization Basic headers” box when setting-up Nextcloud Music. Other If you clicked on the links above, you probably noticed the F-Droid alternative app store for Android.Getting your apps there ensures that you are using verified packages and open-source software. You can easily use it alongside with the Play Store. If that is too inconvenient for you, all of the above apps are also available via the Play Store. Finally, there is the web-browser. If you do not log in with your Google Account, using Chrome is mostly safe. However, I suggest switching to Firefox. See the my original article on that topic for details. In short; the main reason is the availability of extensions. Those allow you to block ads on the mobile web too and use Youtube in the backround. Header Image: Digital Chains by stanjourdan (CC-BY-SA-2.0) 0 0 [Less]
Posted over 1 year ago by Pavel Rojtberg
This post will be for those of you that care about privacy – i.e. if you want that information about you is exclusively under your control.In that context not only Google is to blame, but actually most of the cloud services we know and use today. ... [More] Still Google will serve us as a nice placeholder as it is the market-leader when it comes to providing free services in exchange for your user-profile that Google in turn uses to sell target advertising. Even if you are fine with that, Google is also infamous for killing services – which might hit the one you rely on eventually. As the world is moving mobile-first, a prerequisite for replacing a service is that we can easily integrate the replacement with an Android device.Some might wonder why I chose Android here, given that it is made by Google. See, the problem is not who makes a service/ device, but who controls it. And with Android the main leverage for Google is bundling its services. If you take them away, the device itself is fully under your control – in contrast to Apple/ iOS. Now, that we set the stage, lets start with: Nextcloud At the heart of our efforts will be Nextcloud. This started as an open-source alternative to Dropbox/ Google Drive, but is nowadays grown into a platform for a plethora of different services.The main selling-point is that you can just install Nextcloud on your own machine – ensuring that your data stays private. The software being Open-Source also means that it is not under control of a single corporation – in fact Nextcloud was forked from its predecessor Owncloud after a corporation tried to put the screws on its users. Note, that if you are serious about this, you will need to invest around 500€ to get a machine for hosting that is decently fail-safe. If you rather want to be cheap, you can also just use a RaspberryPi to get away with less than half of that amount. For inspiration, you can take a look on the built I use or on the list of commercial nextcloud device providers. Files & Photos By using the Nextcloud Android App, you can directly replace Google Drive/ Dropbox as this is the core functionality of Nextcloud. Additionally, the App allows you to automatically back-up your Photos/ Videos and free the local storage so you can stop using Google Photos too. Contacts & Calendar Nextcloud also supports Contacts and Calendar out of the box. To integrate them with into your Android Device there is the DAVx5 app. This app will function as an additional data provider, so you can just continue using the stock Google Contacts and Calendar apps. Those will, however, stop sending any data to Google. This is especially useful, if you run a small-business and must ensure that your customer data is private according to the CCPA/ GDPR. Nextcloud News An often overlooked part of your privacy is Google News (also part of Google Now). Each time you view an article there, Google can mine your interests and political views – similar to what Facebook does. And by now you should know where these things can lead. Another drawback here is that the Google Algorithm will create a bubble for you by only showing content coherent with your current world-view.I still prefer to manually choose the news sources – to create that bubble myself. To do that, one usual subscribes some Web-feeds using a Feed aggregator like the Feedly service – similar to what Google Reader used to offer, before being killed by Google. The go-to app here is Nextcloud News combined with the Android App for a pleasant mobile usage. Music Most of you are probably just stream music via Spotify/ Youtube Music, but keep in mind that these services merely rent the songs and as such they can arbitrarily disappear from your library. Therefore, I like to have my own copy of the song. Unfortunately it is very inconvenient to juggle mp3s around for getting the music to various devices. Google Play Music used to offer best of both worlds for me, where you could upload your own music files and manage your playlists in one place. Additionally, you could make the music available offline by pinning individual playlists on your device.Unfortunately, that concept did not allow Google to arbitrarily inject ads into my music stream and therefore the service got killed as well. Nextcloud Music to the rescue! This app picks up your music library via Nextcloud files and allows to stream that via the Browser or the Subsonic API.This is where the Ultrasonic Android Player takes over. As with Play Music, you can either stream the library or pin individual songs/ playlists for offline use. Other If you clicked on the links above, you probably noticed the F-Droid alternative app store for Android.Getting your apps there ensures that you are using verified packages and open-source software. You can easily use it alongside with the Play Store. If that is too inconvenient for you, all of the above apps are also available via the Play Store. Finally, there is the web-browser. If you do not log in with your Google Account, using Chrome is mostly safe. However, I suggest switching to Firefox. See the my original article on that topic for details. In short; the main reason is the availability of extensions. Those allow you to block ads on the mobile web too and use Youtube in the backround. Header Image: Digital Chains by stanjourdan (CC-BY-SA-2.0) 0 0 [Less]