[Google Pixel 2 ROMs, Kernels, Recoveries, & Other ] seanahan:
You are a hero, @npjohnson! I created an XDA account just because I wanted to thank you for maintaining support for the Pixel 2.

For all my fellow Pixel 2 users, I came up with a hacky solution for mitigating the sudden reboot when taking a photo issue that most Pixel 2s with aging batteries experience, and I was wondering if there might be a way to do it better, hopefully one that others can use. (I'm typing this up on my Pixel 2 from memory, so apologies if I misname some of the terms.)

TL;DR: My Pixel 2 will die at around 55% battery if I take a picture. However, using a root debugging adb shell, I can limit the CPU frequencies by writing to /sys/devices/system/cpu/cpufreq/policyX/scaling_max_freq, and then making those "files" read-only. This prevents Android from running the CPU at max clock when you take a photo, and I can successfully take photos down to as low as 27% while still keeping the phone reasonably responsive.

In more detail:

Older batteries have higher internal resistance, so they experience larger voltage sags when supplying larger currents, e.g. when the CPU is being pushed at higher frequencies. If the battery isn't able to supply the system with sufficient voltage, it can trigger a forced low voltage shutdown or even an outright instant shutoff.

Android allows apps to request the system performance profile (power profile?) be adjusted during targeted tasks. These policies are configured by the Android firmware built for a given device, and they control the CPU governor settings, including available CPU frequencies.

The Linux kernel in LineageOS 20 on the Pixel 2 (and I assume across most ARM devices) uses the schedutil governor. Many of its parameters are available via the sysfs interface.

Of particular interest, /sys/devices/system/cpu/cpufreq/policyX/scaling_max_freq is a R/W attribute that controls the max CPU frequency that a group of cores can run at. (The SoC in the Pixel 2 has a big.LITTLE architecture with two clusters, one that is more efficient but lower performance, and the other that is vice versa. Policy0 controls one cluster; policy1 the other, but I can't remember which is which.)

In a root adb shell, I can write some slower limits to those two policies, and then make the files read-only, so Android's policy manager can't overwrite it.

Currently, this "fix" needs to be re-applied after every reboot. I'm using the unofficial LOS20 build that passes SafetyNet checks, and I don't want to fully root the phone until I understand how your unofficial build manages to deal with SafetyNet. So every boot, I connect my phone to my laptop, open up a root adb shell, and run a short shell script that configures scaling_max_freq. I can share my shell script here when I get to my computer next.

Is there a better way? I'd love to be able to more intelligently adjust CPU limits, perhaps taking into account things like the battery temperature, the screen brightness, whether GPS is being used, etc.

I have started recording tables off my phone of battery voltage, core frequencies, temperatures, etc., to find what they all do to voltage sag.

@npjohnson, I'd love to learn more about how you build your unofficial builds. As a more experimental thing on my part, I want to toy around with increasing the firmware partition so more of the Gapps, particularly whatever components are needed to get the "Now Playing" function working and visible on the lock screen, and to get text selection in the task switcher again.

Speaking of the task switcher, with the latest unofficial build, gesture switching seems to only be able to toggle between the current app and the most recent app. Previously, I could swipe right along the bottom repeatedly to switch to older and older apps, but now, it's as if the most recent app almost immediately gets put back onto the top of the task stack. Swiping right just bounces between the most recent two apps. Is there a configurable delay until the task switching is deemed "completed" and the task stack gets reordered?

Anyway, sorry all for the wall of text! Cheers.

–Sean