Louis-Philippe Véronneau - androidhttps://veronneau.org/2022-06-11T00:00:00-04:00Updating a rooted Pixel 3a2022-06-11T00:00:00-04:002022-06-11T00:00:00-04:00Louis-Philippe Véronneautag:veronneau.org,2022-06-11:/updating-a-rooted-pixel-3a.html<p>A short while after <a href="https://veronneau.org/goodbye-nexus-5.html">getting a Pixel 3a</a>, I decided to root it, mostly to
have more control over the charging procedure. In order to preserve battery
life, I like my phone to stop charging at around 75% of full battery capacity
and to shut down automatically at around 12 …</p><p>A short while after <a href="https://veronneau.org/goodbye-nexus-5.html">getting a Pixel 3a</a>, I decided to root it, mostly to
have more control over the charging procedure. In order to preserve battery
life, I like my phone to stop charging at around 75% of full battery capacity
and to shut down automatically at around 12%. Some Android ROMs have extra
settings to manage this, but LineageOS unfortunately does not.</p>
<p>Android already comes with a fairly complex mechanism to handle the charge
cycle, but it is mostly controlled by the kernel and cannot be easily
configured by end-users. <a href="https://github.com/VR-25/acc">acc</a> is a higher-level "systemless" interface for
the Android kernel battery management, but one needs root to do anything
interesting with it. Once rooted, you can use the <a href="https://f-droid.org/en/packages/mattecarra.accapp/">AccA app</a> instead of
playing on the command line to fine tune your battery settings.</p>
<p>Sadly, having a rooted phone also means I need to re-root it each time there is
an OS update (typically each week).</p>
<p>Somehow, I keep forgetting the exact procedure to do this! Hopefully, I will be
able to use this post as a reference in the future :)</p>
<p>Note that these instructions might not apply to your exact phone model, proceed
with caution!</p>
<h2>Extract the boot.img file</h2>
<p>This procedure mostly comes from the <a href="https://wiki.lineageos.org/extracting_blobs_from_zips#extracting-proprietary-blobs-from-payload-based-otas">LineageOS documentation</a> on
extracting proprietary blobs from the payload.</p>
<ol>
<li>
<p>Download the <a href="https://download.lineageos.org/sargo">latest LineageOS image</a> for your phone.</p>
</li>
<li>
<p>unzip the image to get the <code>payload.bin</code> file inside it.</p>
</li>
<li>
<p>Clone the LineageOS scripts git repository:</p>
<p><code>$ git clone https://github.com/LineageOS/scripts</code></p>
</li>
<li>
<p>extract the boot image (requires <code>python3-protobuf</code>):</p>
<p><code>$ mkdir extracted-payload</code>
<code>$ python3 scripts/update-payload-extractor/extract.py payload.bin --output_dir extracted-payload</code></p>
</li>
</ol>
<p>You should now have a <code>boot.img</code> file.</p>
<h2>Patch the boot image file using Magisk</h2>
<ol>
<li>
<p>Upload the <code>boot.img</code> file you previously extracted to your device.</p>
</li>
<li>
<p>Open Magisk and patch the <code>boot.img</code> file.</p>
</li>
<li>
<p>Download the patched file back on your computer.</p>
</li>
</ol>
<h2>Flash the patched boot image</h2>
<ol>
<li>
<p>Enable ADB debug mode on your phone.</p>
</li>
<li>
<p>Reboot into fastboot mode.</p>
<p><code>$ adb reboot fastboot</code></p>
</li>
<li>
<p>Flash the patched boot image file:</p>
<p><code>$ fastboot flash boot magisk_patched-foo.img</code></p>
</li>
<li>
<p>Disable ADB debug mode on your phone.</p>
</li>
</ol>
<h2>Troubleshooting</h2>
<p>In an ideal world, you would do this entire process each time you upgrade to a
new LineageOS version. Sadly, this creates friction and makes updating much more
troublesome.</p>
<p>To simplify things, you can try to flash an old patched <code>boot.img</code> file after
upgrading, instead of generating it each time.</p>
<p>In my experience, it usually works. When it does not, the device behaves
weirdly after a reboot and things that require proprietary blobs (like WiFi)
will stop working.</p>
<p>If that happens:</p>
<ol>
<li>
<p>Download the latest LineageOS version for your phone.</p>
</li>
<li>
<p>Reboot into recovery (Power + Volume Down).</p>
</li>
<li>
<p>Click on "Apply Updates"</p>
</li>
<li>
<p>Sideload the ROM:</p>
<p><code>$ adb sideload lineageos-foo.zip</code></p>
</li>
</ol>Goodbye Nexus 52022-01-23T00:00:00-05:002022-01-23T00:00:00-05:00Louis-Philippe Véronneautag:veronneau.org,2022-01-23:/goodbye-nexus-5.html<p>I've blogged <a href="/running-android-9-pie-on-a-nexus-5-unlegacy-android.html">a few</a> <a href="/musings-on-long-term-software-support-and-economic-incentives.html">times</a> already about my Nexus 5, the Android device I
have/had been using for 8 years. Sadly, it died a few weeks ago, when the WiFi
chip stopped working. I could probably have attempted a mainboard swap, but at
this point, getting a new device …</p><p>I've blogged <a href="/running-android-9-pie-on-a-nexus-5-unlegacy-android.html">a few</a> <a href="/musings-on-long-term-software-support-and-economic-incentives.html">times</a> already about my Nexus 5, the Android device I
have/had been using for 8 years. Sadly, it died a few weeks ago, when the WiFi
chip stopped working. I could probably have attempted a mainboard swap, but at
this point, getting a new device seemed like the best choice.</p>
<p>In a world where most Android devices are EOL after less than 3 years, it is
amazing I was able to keep this device for so long, always running the latest
Android version with the latest security patch. The Nexus 5 originally shipped
with Android 4.4 and when it broke, I was running Android 11, with the November
security patch! I'm very grateful to the FOSS Android community that made this
possible, especially the LineageOS community.</p>
<p>I've replaced my Nexus 5 by a used Pixel 3a, mostly because of the similar form
factor, relatively affordable price and the presence of a headphone jack.
Google also makes flashing a custom ROM easy, although I had more trouble with
this than I first expected.</p>
<p>The first Pixel 3a I bought on eBay was a scam: I ordered an "Open Box" phone
and it arrived all scratched<sup id="fnref:scratch"><a class="footnote-ref" href="#fn:scratch">1</a></sup> and with a broken rear camera. The
second one I got (from the Amazon Renewed program) arrived in perfect condition,
but happened to be a Verizon model. As I found out, Verizon locks the bootloader
on their phones, making it impossible to install LineageOS<sup id="fnref:bootloader"><a class="footnote-ref" href="#fn:bootloader">2</a></sup>. The
vendor was kind enough to let me return it.</p>
<p>As they say, third time's the charm. This time around, I explicitly bought a
phone on eBay listed with a unlocked bootloader. I'm very satisfied with my
purchase, but all in all, dealing with all the returns and the shipping was
exhausting.</p>
<p>Hopefully this phone will last as long as my Nexus 5!</p>
<div class="footnote">
<hr>
<ol>
<li id="fn:scratch">
<p>There was literally a whole layer missing at the back, as if
someone had sanded the phone... <a class="footnote-backref" href="#fnref:scratch" title="Jump back to footnote 1 in the text">↩</a></p>
</li>
<li id="fn:bootloader">
<p>Apparently, an "Unlocked phone" means it is "SIM unlocked",
i.e. you can use it with any carrier. What I should have been looking for is
a "Factory Unlocked phone", one where the bootloader isn't locked :L <a class="footnote-backref" href="#fnref:bootloader" title="Jump back to footnote 2 in the text">↩</a></p>
</li>
</ol>
</div>Lowering the minimum volume on Android2019-12-20T00:00:00-05:002019-12-20T00:00:00-05:00Louis-Philippe Véronneautag:veronneau.org,2019-12-20:/lowering-the-minimum-volume-on-android.html<p>I like music a lot and I spend a large chunk of my time with either over-the-ear
headphones or in-ear monitors on. Sadly, human ears are fragile things and you
should always try to keep the volume as low as possible when using headphones.</p>
<p>When I'm not at home, I …</p><p>I like music a lot and I spend a large chunk of my time with either over-the-ear
headphones or in-ear monitors on. Sadly, human ears are fragile things and you
should always try to keep the volume as low as possible when using headphones.</p>
<p>When I'm not at home, I usually stream music from my home server to my Android
device. Although the DAC quality on my Nexus 5 isn't incredible, my IEMs aren't
stellar either.</p>
<p>Sadly, I've always been displeased with how little control Android actually
gives you over the media volume and I've always wished I could have the lowest
setting even lower.</p>
<p>I know a bunch of proprietary apps exist on the Google Play Store to help you
achieve that kind of thing, but hey, I don't swing that way.</p>
<h2>Android Audio Policies</h2>
<p>After having a look at Android's <a href="https://source.android.com/devices/audio/implement-policy">audio policies documentation</a>, it
turns out if you have a rooted device, you can define the audio level curve
yourself!</p>
<p>On a recent-ish version of Android, the two files you want to mess with are:</p>
<ul>
<li>
<p><code>/vendor/etc/audio_policy_volumes.xml</code>, which defines what type of audio
stream (media, phone calls, earbuds, bluetooth, etc.) uses what type of audio
curve.</p>
</li>
<li>
<p><code>/vendor/etc/default_volume_tables.xml</code>, which defines the default audio
curves referenced in the previous file.</p>
</li>
</ul>
<p>If you've never modified files on Android, I highly recommend plugging your
device to a computer, enabling USB debugging and connecting through <code>adb</code>. You
will likely need to remount the filesystem, as it's in read-only mode by
default:</p>
<pre>
$ adb shell
$ su
$ mount -o remount,rw /system
</pre>
<p>I don't really care about anything else than media volume, so here is the curve
I ended up with. It goes very low and gives you more control at low volume,
while still being quite loud at maximum volume. You will need to experiment with
your device though, as DACs are all different.</p>
<div class="highlight"><pre><span></span><code><span class="nt"><reference</span><span class="w"> </span><span class="na">name=</span><span class="s">"DEFAULT_MEDIA_VOLUME_CURVE"</span><span class="nt">></span>
<span class="cm"><!-- Default Media reference Volume Curve --></span>
<span class="w"> </span><span class="nt"><point></span>1,-9000<span class="nt"></point></span>
<span class="w"> </span><span class="nt"><point></span>10,-8000<span class="nt"></point></span>
<span class="w"> </span><span class="nt"><point></span>20,-7000<span class="nt"></point></span>
<span class="w"> </span><span class="nt"><point></span>30,-6000<span class="nt"></point></span>
<span class="w"> </span><span class="nt"><point></span>40,-4000<span class="nt"></point></span>
<span class="w"> </span><span class="nt"><point></span>60,-3000<span class="nt"></point></span>
<span class="w"> </span><span class="nt"><point></span>100,-2000<span class="nt"></point></span>
<span class="nt"></reference></span>
</code></pre></div>
<p>For reference, the scale goes from <code>-9600</code> to <code>0</code>, <code>0</code> being the loudest sound
your device can produce.</p>
<p>As all things Android, if you are not building your own images, this will get
erased next time you update your device. Don't forget to backup the files you
modify, as audio curves are easy to screw up!</p>Running Android 9 (Pie) on a Nexus 5 -- Unlegacy Android2019-04-24T00:00:00-04:002019-04-24T00:00:00-04:00Louis-Philippe Véronneautag:veronneau.org,2019-04-24:/running-android-9-pie-on-a-nexus-5-unlegacy-android.html<p>Like most good stories, this one starts in a bar with friends. <a href="https://veronneau.org/debconf-videoteam-sprint-fosdem-report.html">I had the chance
to go to FOSDEM this year</a> and I managed to get a bunch of people from
the DebConf videoteam to meet me at Brew Dog Bruxelles.</p>
<p>Like the respectable geeks we are, the first …</p><p>Like most good stories, this one starts in a bar with friends. <a href="https://veronneau.org/debconf-videoteam-sprint-fosdem-report.html">I had the chance
to go to FOSDEM this year</a> and I managed to get a bunch of people from
the DebConf videoteam to meet me at Brew Dog Bruxelles.</p>
<p>Like the respectable geeks we are, the first thing we did after exchanging
greeting was to connect to the local Wi-Fi. That's when Stefano Rivera looked
at my phone and casually said: “Wow, that's running Android 7, it's <em>ancient!</em>”.</p>
<p>I've had my Nexus 5 for a while now. If I recall correctly, I bought it sometime
in Q1 2014. Although already dated at the time, it was a great phone: fast,
cheap and easy to repair. The Nexus 5 hasn't been supported by Google for years,
but until recently LineageOS did a great job at keeping the OS patched and
updated. Sadly, it seems my device won't get ported to LineageOS 16. <a href="https://lineageos.org/Changelog-22/">As
announced here</a>, the 14.1 branch won't get security support anymore.</p>
<p>Lucky for me, I found the amazing <a href="https://forum.xda-developers.com/google-nexus-5/orig-development/rom-unlegacy-android-project-t3593425">Unlegacy Android</a> project. Their
goal is to build and patch the Android Open Source Project (AOSP) for older
devices. The difference with LineageOS is that they do not customize the ROMs,
thus making patch porting easier and less troublesome. A few models are
supported, but their main focus is the Nexus 5.</p>
<h2>Installing Unlegacy Android</h2>
<p>If you have a Nexus 5 and want to upgrade to a bleeding edge version of Android,
you have two options:</p>
<ol>
<li>You can install one of the builds provided by the Unlegacy Android project.
Since they still consider Android 9 experimental (even though it works
pretty much flawlessly), those builds are hosted on a <a href="https://notredame.app.box.com/s/26a4bygh9vbaw7jjq08xr5evomvaw5ww">shady box.com cloud
storage</a>.</li>
<li>You can build the ROM yourself, following the <a href="https://wiki.lineageos.org/devices/sailfish/build">LineageOS wiki</a>
instruction while replacing the code repository with the <a href="https://github.com/Unlegacy-Android">Unlegacy</a>
one.</li>
</ol>
<p>Although it's a bit more work, I prefer to build the project myself. Something
about downloading an update from a random box.com cloud storage doesn't feel
right to me. Once a month, when the monthly <a href="https://source.android.com/security/bulletin/">Android Security Patch</a>
is merged in the Unlegacy repository, I boot a VM on my server and build a new
OTA update.</p>
<p>Unlegacy Android also provides official <a href="https://builds.unlegacy-android.org/">Android 7 and Android 8
builds</a> if you are into that.</p>
<h2>What about bugs?</h2>
<p>I've been using Unlegacy Android with the latest Android 9 builds for 3 months
now and the only bugs I've experienced are:</p>
<ul>
<li>On an encrypted device, TWRP isn't able to decrypt the partitions, rendering
it somewhat useless. You can still update the device via ADB sideload though.</li>
<li>Bluetooth voice calls (HFP) are garbled. Playing music via A2DP works fine
though.</li>
</ul>
<p>I also seen more random app crashes than when I was using LineageOS 14.1, but
nothing extreme. The overall experience is great: my device is snappy, runs the
latest AOSP build and I neither have bloatware nor Google Apps.</p>
<p>All in all, considering new phones running Android 9 start at 500 USD and that
you can buy a new Nexus 5 for less than 100 USD on ebay, it's a pretty
compelling choice.</p>