<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
	<channel>
		<title>Android on tsvinc</title>
		<link>https://tsvinc.dev/tags/android/</link>
		<description>Recent content in Android on tsvinc</description>
		<generator>Hugo</generator>
		<language>en-us</language>
		
		
		
		
			<lastBuildDate>Sun, 22 Feb 2026 00:00:00 +0000</lastBuildDate>
		
			<atom:link href="https://tsvinc.dev/tags/android/index.xml" rel="self" type="application/rss+xml" />
			<item>
				<title>HTC Desire Z GPS: the Ghidra fix that landed 235 km away</title>
				<link>https://tsvinc.dev/posts/60kb-gps-fix/</link>
				<pubDate>Sun, 22 Feb 2026 00:00:00 +0000</pubDate>
				<guid>https://tsvinc.dev/posts/60kb-gps-fix/</guid>
				<description>&lt;p&gt;For one night, this looked like the best result of the whole project. My HTC Desire Z, the 2010 Android slider that by then had its camera button wired to a waypoint logger, had spent hours by a window failing to find itself. Then I opened its 60 KB GPS library in Ghidra, found a switch that throws away &amp;quot;intermediate&amp;quot; positions, turned the switch on and rebooted. Two seconds after I pressed the camera button, a coordinate landed in the waypoint file. Six decimal places. Accuracy: zero metres.&lt;/p&gt;</description>
			</item>
			<item>
				<title>HTC Desire Z battery tile: the SD card its launcher can&#39;t write</title>
				<link>https://tsvinc.dev/posts/118ma-fuel-gauge-tile/</link>
				<pubDate>Sun, 11 Jan 2026 00:00:00 +0000</pubDate>
				<guid>https://tsvinc.dev/posts/118ma-fuel-gauge-tile/</guid>
				<description>&lt;p&gt;The first builds of the logger turned the tile green and wrote nothing. The fifth place I tried to put its file worked. About thirteen hours after the first of those builds, I moved the file to the SD card on principle, and well after midnight I found it had written nothing again. The tile itself, the part with actual logic in it, took one build.&lt;/p&gt;&#xA;&lt;p&gt;The tile lives on MeshLauncher, the home screen I wrote for my HTC Desire Z, a 2010 phone on CyanogenMod 7 (Android 2.3, a community build) where I had started replacing stock apps with small ones of my own. MeshLauncher &lt;a href=&#34;https://tsvinc.dev/posts/aosp-test-keys/&#34;&gt;runs as UID 1000&lt;/a&gt;, the system user, because this build trusts the platform key it is signed with. Hold on to that UID; it is the villain. The tile shows the phone&#39;s current draw from a kernel file, &lt;code&gt;smem_text&lt;/code&gt;, which &lt;a href=&#34;https://tsvinc.dev/posts/power-monitoring-sysfs/&#34;&gt;the previous post&lt;/a&gt; takes apart. Tap it and it logs one CSV line every ten seconds. This post is the day it took to find a directory that would accept those lines.&lt;/p&gt;</description>
			</item>
			<item>
				<title>HTC Desire Z battery drain in milliamps, straight from sysfs</title>
				<link>https://tsvinc.dev/posts/power-monitoring-sysfs/</link>
				<pubDate>Sun, 19 Oct 2025 00:00:00 +0000</pubDate>
				<guid>https://tsvinc.dev/posts/power-monitoring-sysfs/</guid>
				<description>&lt;p&gt;The battery icon said 100% for the whole session, and it was telling the truth. The phone was on a USB cable and full, so 100% was the correct answer to a question I had stopped asking. The number I wanted sat one layer down. In one 70-second stretch of my log, the phone&#39;s estimated time left on a full charge went from 6.8 hours to 15.3 and the percentage did not twitch. I have a soft spot for a gauge that is accurate and useless at the same time. This one gets a place on the shelf.&lt;/p&gt;</description>
			</item>
			<item>
				<title>Packing a battery-first kernel into an HTC Desire Z boot.img</title>
				<link>https://tsvinc.dev/posts/battery-first-kernel/</link>
				<pubDate>Thu, 07 Aug 2025 00:00:00 +0000</pubDate>
				<guid>https://tsvinc.dev/posts/battery-first-kernel/</guid>
				<description>&lt;p&gt;Before I built a kernel for my HTC Desire Z, I wrote a plan for it, and the plan was confident about the end. Build the kernel and its modules, dump the boot partition, take the image apart, swap the kernel, put it back, flash it, check the frequency table, measure idle current. The middle of that, everything between &amp;quot;dump&amp;quot; and &amp;quot;flash&amp;quot;, was a single comment line. I wrote that line. I have some notes for the man who wrote it.&lt;/p&gt;</description>
			</item>
			<item>
				<title>HTC Desire Z custom kernel killed Wi-Fi: version magic and insmod</title>
				<link>https://tsvinc.dev/posts/wifi-version-magic/</link>
				<pubDate>Fri, 30 May 2025 00:00:00 +0000</pubDate>
				<guid>https://tsvinc.dev/posts/wifi-version-magic/</guid>
				<description>&lt;p&gt;The fix, for anyone in a hurry: rebuild the Wi-Fi module from inside the kernel tree, take one &lt;code&gt;-Werror&lt;/code&gt; out of the Broadcom driver&#39;s Makefile, copy the new &lt;code&gt;bcm4329.ko&lt;/code&gt; over the old one in &lt;code&gt;/system/lib/modules&lt;/code&gt;, and reboot. On the way I also added a firmware symlink, and for a while I believed the symlink was the second half of the fix. It was the second half of a mistake I had made a few minutes earlier, and this post is mostly about how I found that out after the fact.&lt;/p&gt;</description>
			</item>
			<item>
				<title>Desire Z undervolt: a battery kernel next to CONFIG_JESUS_PHONE</title>
				<link>https://tsvinc.dev/posts/config-jesus-phone-undervolt/</link>
				<pubDate>Mon, 21 Apr 2025 00:00:00 +0000</pubDate>
				<guid>https://tsvinc.dev/posts/config-jesus-phone-undervolt/</guid>
				<description>&lt;p&gt;The whole job, in the order it happened: twelve minutes of reading kernel source and writing a plan, a defconfig, an undervolt, three build failures, seven hours in which nobody touched it, a fourth build failure, a successful build, one &lt;code&gt;fastboot flash boot&lt;/code&gt;, and a phone that came back up on a kernel I had compiled myself. The phone is my HTC Desire Z, the 2010 keyboard slider that runs CyanogenMod 7 (Android 2.3) in this series, and that I had just told, in so many words, to put its battery ahead of everything else. Speed second. Fun, apparently, third.&lt;/p&gt;</description>
			</item>
			<item>
				<title>HTC Desire Z browsers: what still loads HTTPS on Android 2.3</title>
				<link>https://tsvinc.dev/posts/gingerbread-browsers/</link>
				<pubDate>Fri, 14 Feb 2025 00:00:00 +0000</pubDate>
				<guid>https://tsvinc.dev/posts/gingerbread-browsers/</guid>
				<description>&lt;p&gt;This was going to be a browser review. The research gave me five candidates for Android 2.3 and a column for how each one does HTTPS. One of the five ever ran on the phone, not in the version at the top of the list, and the most thorough part of the exercise turned out to be reading release notes. I have reviewed worse things more favourably.&lt;/p&gt;&#xA;&lt;p&gt;The phone is an HTC Desire Z, a 2010 slider with a hardware keyboard, running CyanogenMod 7, which is Android 2.3 with an older web stack than any site I visit expects. The question for this part is narrow: which browsers on that phone can still open a modern HTTPS site, and why those and not the others. The answer has nothing to do with rendering. It is decided by where the TLS handshake happens.&lt;/p&gt;</description>
			</item>
			<item>
				<title>Terraria on the HTC Desire Z: a DRM loop and a dead edge</title>
				<link>https://tsvinc.dev/posts/terraria-dead-zone/</link>
				<pubDate>Sat, 28 Dec 2024 00:00:00 +0000</pubDate>
				<guid>https://tsvinc.dev/posts/terraria-dead-zone/</guid>
				<description>&lt;p&gt;My thumb is on the row of hearts at the top of the screen, and nothing happens. Not a slow response, not a wrong item selected: the game behaves as if the thumb is somewhere else entirely. Tapping again, slower and with more conviction, is a debugging technique with a perfect record of not working, and it kept that record. By the end of the afternoon I had patched the game&#39;s license check three times, signed it with two different keys and swapped it for a newer build, all to arrive at a screen I could not touch.&lt;/p&gt;</description>
			</item>
			<item>
				<title>A camera app for the HTC Desire Z, cut from 13,144 lines to 881</title>
				<link>https://tsvinc.dev/posts/meshcam-android-gingerbread/</link>
				<pubDate>Tue, 12 Nov 2024 00:00:00 +0000</pubDate>
				<guid>https://tsvinc.dev/posts/meshcam-android-gingerbread/</guid>
				<description>&lt;p&gt;The plan was a fork. Take AnonCam, an open-source camera built on the Android 2.3 camera app, delete what my phone does not need, keep the rest. What shipped is 881 lines, and the part of AnonCam still in it fits in three files, renamed and cut down. I call that a fork the way I call a house with one original doorframe a renovation: technically, and only when nobody is checking the paperwork.&lt;/p&gt;</description>
			</item>
			<item>
				<title>HTC Desire Z journal app: 8 KB that would not fit in 900 MB</title>
				<link>https://tsvinc.dev/posts/journal-app-android-gingerbread/</link>
				<pubDate>Wed, 04 Sep 2024 00:00:00 +0000</pubDate>
				<guid>https://tsvinc.dev/posts/journal-app-android-gingerbread/</guid>
				<description>&lt;p&gt;The package manager looked at an APK of 8,482 bytes, looked at a &lt;code&gt;/data&lt;/code&gt; partition that &lt;code&gt;df&lt;/code&gt; had just reported with 928,136 KB available, and answered &lt;code&gt;INSTALL_FAILED_INSUFFICIENT_STORAGE&lt;/code&gt;. I have been lied to by this phone before, Android, but rarely with the evidence printed on the same screen a few commands earlier.&lt;/p&gt;&#xA;&lt;p&gt;The phone is my HTC Desire Z, a 2010 slider with a hardware keyboard, running CyanogenMod 7 (the community build of Android 2.3); these days most of what runs on it is code I compiled myself with a Java 6 toolchain, because almost nothing current installs. This part is about one more such app: a journal that keeps one plain text file per day. Writing it took an evening. Getting the phone to accept it, test it and photograph it took the rest of that evening, and the photograph came with a correction to my own notes.&lt;/p&gt;</description>
			</item>
			<item>
				<title>HTC Desire Z screenshots on Android 2.3, the long way round</title>
				<link>https://tsvinc.dev/posts/screenshot-toast-war/</link>
				<pubDate>Sun, 09 Jun 2024 00:00:00 +0000</pubDate>
				<guid>https://tsvinc.dev/posts/screenshot-toast-war/</guid>
				<description>&lt;p&gt;How hard is it to get a picture of a phone&#39;s screen when you have root on the phone, its bootloader unlocked and a keyboard attached? I needed a few screenshots of MeshLauncher, the home-screen app I had just written for my HTC Desire Z, a 2010 Android slider with a four-row keyboard that I&#39;m rebuilding around software of my own. It runs CyanogenMod 7, the community build of Android 2.3, and on that ROM the honest answer is: hard enough that I ended up signing my app with Google&#39;s published platform key. Phones that refuse simple requests get my full attention, which has never once been good news for the phone or for my evening.&lt;/p&gt;</description>
			</item>
			<item>
				<title>HTC Desire Z launcher keys: ADW&#39;s Back trick and two wrong fixes</title>
				<link>https://tsvinc.dev/posts/25kb-launcher-part-2/</link>
				<pubDate>Tue, 02 Apr 2024 00:00:00 +0000</pubDate>
				<guid>https://tsvinc.dev/posts/25kb-launcher-part-2/</guid>
				<description>&lt;p&gt;Android&#39;s documentation for &lt;code&gt;KeyEvent.FLAG_CANCELED&lt;/code&gt; says, in one paragraph, that an app should not act on a key until the key&#39;s up event arrives, because the press can still be canceled. I learned that rule the expensive way: my launcher acted on Back too early, I went looking in someone else&#39;s launcher for the fix, found it, and only afterwards read the paragraph that had been sitting in the class I was calling all along.&lt;/p&gt;</description>
			</item>
			<item>
				<title>A 22 KB home screen for the HTC Desire Z, built without Gradle</title>
				<link>https://tsvinc.dev/posts/22kb-launcher/</link>
				<pubDate>Fri, 15 Mar 2024 00:00:00 +0000</pubDate>
				<guid>https://tsvinc.dev/posts/22kb-launcher/</guid>
				<description>&lt;p&gt;I assumed the cheap way to get a small launcher was to take an existing one and cut. The phone is an HTC Desire Z, the 2010 Android slider with a full keyboard, which I&#39;m turning into a field device for a mesh network, on CyanogenMod 7, the community build of Android 2.3. Its home screen app is ADWLauncher, and I had its source open on my desk with every intention of carving it down to three screens.&lt;/p&gt;</description>
			</item>
			<item>
				<title>HTC Desire Z Home button dead on CM7: nine suspects, no culprit</title>
				<link>https://tsvinc.dev/posts/home-key-archaeology/</link>
				<pubDate>Mon, 08 Jan 2024 00:00:00 +0000</pubDate>
				<guid>https://tsvinc.dev/posts/home-key-archaeology/</guid>
				<description>&lt;p&gt;Above the Home-key code in Android 2.3&#39;s window manager sits a comment promising that the system handles Home itself, &amp;quot;so applications can never break it&amp;quot;. I have read that comment many times now, and every time I agree with it a little less. On my HTC Desire Z, a 2010 Android slider I keep around for its keyboard, running CyanogenMod 7 (the community build of Android 2.3), Home did nothing at all. No crash, no wrong app, no delay. A tap on the leftmost button below the screen, a little feedback from the phone, and then the same app still sitting there.&lt;/p&gt;</description>
			</item>
			<item>
				<title>Android test-keys: system UID with AOSP&#39;s public platform key</title>
				<link>https://tsvinc.dev/posts/aosp-test-keys/</link>
				<pubDate>Fri, 22 Dec 2023 00:00:00 +0000</pubDate>
				<guid>https://tsvinc.dev/posts/aosp-test-keys/</guid>
				<description>&lt;p&gt;My HTC Desire Z, a 2010 slider phone, runs CyanogenMod 7, a custom build of Android 2.3, and I wanted my own small apps on it to do system things: toggle GPS from a background service, take screenshots without the su toast popping up each time. The usual route is root, and root on this ROM announces itself every time, like a butler who insists on reading your name out at your own front door. This part is the other route, which the ROM leaves open by default.&lt;/p&gt;</description>
			</item>
			<item>
				<title>HTC Desire Z boot hang, an innocent cache wipe, and a reflash</title>
				<link>https://tsvinc.dev/posts/cache-wipe-bricked-boot/</link>
				<pubDate>Wed, 11 Oct 2023 00:00:00 +0000</pubDate>
				<guid>https://tsvinc.dev/posts/cache-wipe-bricked-boot/</guid>
				<description>&lt;p&gt;The boot animation loops. Animated circles, no launcher, no error, and it has been at it long enough that I have stopped expecting the next loop to be the last. The phone is an HTC Desire Z, the 2010 Android slider with a hardware keyboard that I&#39;m setting up for mesh networking, on CyanogenMod 7 (Android 2.3, on the Dalvik VM) with ClockworkMod (CWM) recovery, the small maintenance system the phone boots instead of Android to flash and wipe, and the last thing I did to it was put in an SD card.&lt;/p&gt;</description>
			</item>
			<item>
				<title>HTC Desire Z: three black screens and a brightness of 30</title>
				<link>https://tsvinc.dev/posts/brightness-30/</link>
				<pubDate>Wed, 27 Sep 2023 00:00:00 +0000</pubDate>
				<guid>https://tsvinc.dev/posts/brightness-30/</guid>
				<description>&lt;p&gt;I keep a ledger for nights like this one. The entry reads: three black screens in twenty-two minutes, three different exits, and a number attached to exactly one of them. The phone is an HTC Desire Z, the 2010 Android slider with a keyboard that I&#39;m slimming down into a mesh-network node, running CyanogenMod 7, the community build of Android 2.3. I had just pulled most of its system apps and was writing my own home screen for it, and three times the screen came back lit and empty: backlight on, nothing drawn.&lt;/p&gt;</description>
			</item>
			<item>
				<title>Debloating Android 2.3 on the HTC Desire Z: use pm disable</title>
				<link>https://tsvinc.dev/posts/cm7-bloat-dependency-map/</link>
				<pubDate>Thu, 03 Aug 2023 00:00:00 +0000</pubDate>
				<guid>https://tsvinc.dev/posts/cm7-bloat-dependency-map/</guid>
				<description>&lt;p&gt;The careful way to strip a ROM is to delete nothing, and that is how I set out to strip CyanogenMod 7.2.0, the community build of Android 2.3, on an HTC Desire Z: a 2010 phone with a slide-out keyboard that I&#39;m turning into a pocket terminal for a mesh network. Every unwanted system APK would move out of &lt;code&gt;/system/app/&lt;/code&gt; into &lt;code&gt;/system/app-disabled/&lt;/code&gt;. Reversible, nothing deleted, every step undone with one &lt;code&gt;mv&lt;/code&gt;.&lt;/p&gt;</description>
			</item>
			<item>
				<title>HTC Desire Z bought for parts: S-OFF, SuperCID and 4202 mV</title>
				<link>https://tsvinc.dev/posts/4202-millivolts/</link>
				<pubDate>Fri, 14 Jul 2023 00:00:00 +0000</pubDate>
				<guid>https://tsvinc.dev/posts/4202-millivolts/</guid>
				<description>&lt;p&gt;It arrived as a parts phone: an HTC Desire Z, the 2010 Android slider with a four-row hardware keyboard, bought as a donor for whatever still worked. I expected a cracked digitizer and a battery swollen into a pillow. Then I plugged it in, and every question I asked it over USB came back with better news than the last. When a phone from 2010 starts doing that, I stop enjoying it and start keeping notes.&lt;/p&gt;</description>
			</item>
	</channel>
</rss>
