Recently I got a new phone and immediately had trouble with my notifications coming in on time. Emails, calendar alerts, even alarms were being delayed up to 15 minutes.

This isn’t the first time I’ve had problems like this. When Doze first came out back in Android 6 around 2017, it caused me a lot of grief, until I figured out how to whitelist apps and disable it. However, none of my well-known fixes and workarounds were effective.

A new sinister menace has arisen. It’s the Cached Apps Freezer, and it must die.

Before I wrote this post, I did a lot of research and found very little information. It’s clear that this feature and it’s negative side effects is not well know to the Android user community. The one exception was the Termux community and it’s dev agnostic-apollo, who had some excellent notes which I link to below.

The Cached Apps Freezer first appeared in Android 11 QPR3. It’s a feature that still seems half baked, like it’s in beta, but it’s being enabled by default on some devices. Notably, all Google Pixel devices have it enabled by default, but I’ve read that some Samsung devices also have it enabled by default.

So what does it do? In basic English, it periodically pauses and unpauses any app that isn’t in the foreground so that it can’t run. The process isn’t killed, but it can’t do anything until it gets unfrozen. If you watch your logcat, you will regularly see ActivityManager messages with the word “freeze” and “frozen”. It’s a power saving feature and you will find a plenty of ignorant users praising how it makes their battery last longer, but you won’t find any mention of the side effect of delaying notifications.

Note that you might have seen the term “frozen” and “freeze” before in relation to Android apps, where the app is still installed but disabled. This is not the same thing and is not related in any way.

If battery life is your primary concern, then feel free to turn this thing on. It definitely works, but don’t expect your notifications to come in right away. They might come in instantly, but most of the time they are going to be delayed up to 15 minutes.

So, what can you do about it if you want it disabled?

Unfortunately this feature has no user-facing control. Google didn’t create any kind of knobs or controls for the end-user. Maybe this is intentional, or maybe it’s just a half-baked feature. Either way, your only option is to disable it completely.

There are two ways to disable it:

Option 1: Enable Developer Options and disable “Suspend execution for cached apps”. You must reboot to apply the change.

Option 2: Run the following command on an adb shell, a terminal, or wherever, and then reboot: “device_config put activity_manager_native_boot use_freezer false”.

Below are a bunch of links with reference info.

https://source.android.com/docs/core/perf/cached-apps-freezer

https://www.xda-developers.com/hidden-changes-android-11-source-code/

https://discuss.grapheneos.org/d/11574-cached-apps-freezer-breaking-foreground-services-pixel-7pro-qpr2

https://www.reddit.com/r/termux/comments/13z7cpg/prevent_termux_from_closing/

https://github.com/termux/termux-app/issues/2366

https://github.com/agnostic-apollo/Android-Docs/blob/master/en/docs/apps/processes/phantom-cached-and-empty-processes.md

  • henfredemars@infosec.pub
    link
    fedilink
    English
    arrow-up
    19
    arrow-down
    3
    ·
    8 months ago

    I work on Android professionally both in building our own apps as well as reverse engineering existing ones alongside Android system processes, the Android kernel, and device firmware. There’s a lot of FUD here and not a lot of actual information in the comments. Perhaps I can provide some perspective.

    In the beginning, Android was everything that Apple was not. Liberal and open, app developers were given almost complete freedom. The young OS needed a thriving ecosystem yesterday to challenge the App Store. This is reflected in other choices that still live with us today, like the choice of the Java programming language and its garbage collection to keep the ecosystem familiar and easy to learn for developers. This has led to chronic memory struggles, but that’s a discussion for another time.

    Today, there is no need for explosive development. The Play Store is overflowing. We have the quantity. Now, the problem is app quality. It turns out that developers are selfish and cannot be trusted to be good stewards of shared, limited system resources. It’s easy to understand why. Developing an app is no small feat, and it’s natural to become attached when in reality your app might not mean the world to every user. Other developers wish to collect your data, and are happy to expend resources in ways that don’t benefit you. Permissions were added, sandboxing, and eventually Android decided to tie user interaction to system resources.

    The idea is that if an app is important to the user, they ought to actually be using it, no? Whenever you use an app or interact with a notification, you’re telling Android that this program is important. Timers and events can fire more frequently, and the OS is more willing to perform background work. Apps you don’t use much are throttled, but they can still show a notification immediately if designed properly to respond to external events. More on this later. Remember: Android must decide where to spend your limited resources because apps cannot be trusted to do this amongst themselves.

    The App Freezer takes this principal to the extreme. If you’re not actively interacting with an app, it gets zero resources. Nothing! It cannot run. The app is stopped. If you want to run, you need some external push to trigger access to resources. For example, the user could tap the app icon. A server might push a notification which will cause Android to unfreeze the app to handle it. You can also set timers or schedule the app to run on other conditions, but whether or not those things actually happen is up to the OS assessment for how important you are to the user, and app functionality must be driven through these events.

    Many methods to trigger running are frequently abused by applications that don’t want to remodel. For example, a lazy developer could set a timer to trigger running an app every five minutes to check email. This is a really bad design because we have to keep the app in memory all the time and able to run which waste the battery. An app shouldn’t check for anything by polling. Rather, the email provider should tell Android to trigger the app to run on your phone whenever an email arrives, even if the app isn’t running! Push. Don’t pull the data. no useless spinning. It runs only when the email arrives and at no other time.

    Android is taking a firm stand with the Freezer. You must redesign your app to respond to new data as it arrives or your app simply won’t work correctly. This is a complete reversal of responsibilities where your app is driven from the outside instead of the app doing the driving. A correctly written, well-behaved app will look almost inside out because it’s called upon to handle events rather than performing actions to check for events. This is a better design because keeping applications running all the time is not sustainable as users install more apps. iOS had the right idea of being extremely conservative with background services in the beginning. Android is still trying to bend apps to submit to the OS rather than the other way around.

    If a party is at fault here, it’s Google. It’s irresponsible to allow apps to simply malfunction because this is a poor user experience. Notifications are delayed, and users don’t understand what’s wrong. It is my opinion that this problem occurs because Google did not provide sufficient developer support to redesign applications. To make matters worse, the behavior is highly inconsistent because every handset developer has slightly different rules for what constitutes important and exactly how resources are assigned. Sometimes, a badly designed app will work just fine until one day the OS decides it’s not important right now and you miss an update. to the user, the app looks flaky and to the developer sometimes it’s working so is there really a bug?

    I’m not proposing a solution. I’m only here to explain the problem. App developers are not respecting Google’s intent, and Google is not providing adequate support for these apps when they inevitably fail. This is a decade old problem that resurfaces yet again as Google continues to build on this idea that apps only run based on external events while many apps continue to rely on polling.

    • JM9@lemmy.world
      link
      fedilink
      English
      arrow-up
      1
      ·
      edit-2
      8 months ago

      Many methods to trigger running are frequently abused by applications that don’t want to remodel. For example, a lazy developer could set a timer to trigger running an app every five minutes to check email. This is a really bad design because we have to keep the app in memory all the time and able to run which waste the battery. An app shouldn’t check for anything by polling. Rather, the email provider should tell Android to trigger the app to run on your phone whenever an email arrives, even if the app isn’t running! Push. Don’t pull the data. no useless spinning. It runs only when the email arrives and at no other time.

      Thank you for the detailed post. Something still doesn’t compute here because one of the email apps that gets put in the freezer is Google’s own Gmail app. If your explanation is correct, what does it say about the fact that Google can’t convince their own developers to do the right thing. Overall pretty sad state of affairs as far as push notifications on Android go.