cd /news/artificial-intelligence/nobody-painted-that-rectangle-black · home topics artificial-intelligence article
[ARTICLE · art-62440] src=dev.to ↗ pub= topic=artificial-intelligence verified=true sentiment=· neutral

Nobody Painted That Rectangle Black

Maneshwar, a developer, explains the technical mechanism behind black rectangles in screenshots of protected content like Netflix videos and banking apps. On Android, SurfaceFlinger composites separate images per output destination, skipping layers with the FLAG_SECURE flag for screenshots, leaving untouched memory (zeros) that appear black. The protection is a software policy that can be bypassed with root access, unlike Widevine L1 DRM which enforces hardware-level protection via the TEE.

read5 min views1 publishedJul 16, 2026

Hello, I'm Maneshwar. I'm building git-lrc, a Micro AI code reviewer that runs on every commit. It is free and source-available on Github. Star git-lrc to help devs discover the project. Do give it a try and share your feedback.

You have done this.

Netflix is playing, something on screen is worth sharing, you hit screenshot, and you get a black rectangle where the video was.

The play button is there. The scrubber is there.

The actual show? Gone.

Same deal with screen recording, except weirder.

You are staring directly at the video while it plays, perfectly visible, in full color, and the saved recording comes out black.

Your eyes say one thing. The file says another.

Most of us file this under "Netflix blocked it" and move on with our lives.

But the mechanism underneath is stranger and honestly more elegant than "blocked."

So let's go layer by layer.

Here is what I assumed:

Reasonable. Also completely wrong.

Nothing detects anything. Nothing paints anything.

Sit with that, because the rest of this post falls out of it.

Here is the load-bearing idea, and it took me embarrassingly long to arrive at it: the screen and the screen recorder are not looking at the same image.

I had assumed there was one framebuffer, one canonical "what the phone currently looks like," and that a screenshot was simply a copy of it.

Nope. SurfaceFlinger, Android's compositor, does not render one image that everybody shares.

It renders a separate composite per output destination.

The physical panel is one destination.

The screenshot service is another. A cast session is a third.

For each destination, SurfaceFlinger walks the layer list and asks exactly one question per layer: does this layer belong in this output? For the panel, the answer is always yes.

For the screenshot output, any layer carrying FLAG_SECURE

gets skipped.

So the video layer is never removed from the screenshot if its is never added.

This is my favorite part.

The capture buffer gets allocated and zeroed.

Normal layers write into it. The secure layer does not. Then the buffer gets encoded and handed over.

Zeros are black.

That is the whole thing. Nobody chose black.

There is no paintItBlack()

sitting in AOSP.

Black is simply what untouched memory looks like when you interpret it as pixels. The rectangle is not censored, it is vacant.

It is the absence of a decision.

This also explains something I had seen a hundred times and never once registered: the black is exactly the video's shape, and the UI around it survives just fine.

Play button, scrubber, title text, all present.

Those are separate layers. Only one of them had the flag.

So I went and screenshotted my banking app.

Same black frame. Password manager, same.

Whatsapp one view image screenshot? same.

Here is the entire implementation:

getWindow().setFlags(
    WindowManager.LayoutParams.FLAG_SECURE,
    WindowManager.LayoutParams.FLAG_SECURE
);

One call. Thirty seconds of work. That is the feature, shipped.

Everything so far is a policy.

SurfaceFlinger chooses to honor FLAG_SECURE

.

The pixels sit in perfectly ordinary memory the whole time.

The compositor is just politely declining to copy them.

Which means: root the phone, patch SurfaceFlinger, flag ignored, banking screenshots work again. The whole protection is a gentleman's agreement enforced by code that the root user owns.

Netflix HD is not that.

With Widevine L1, decoded frames live inside the TEE, a separate secure world running on the same SoC.

The decrypted video never lands in memory the application processor can address.

It goes from the TEE into a protected buffer, gets composited, reaches your eyeballs, and the kernel never touches a single pixel of it.

There is no code to patch, because it is not code.

It is the memory controller saying no, in silicon xD

Mechanism Enforced by Defeated by
Banking app FLAG_SECURE
The OS, voluntarily Root
Netflix HD
FLAG_SECURE + L1 secure buffers
The chip itself Nothing on the device

Here is where I stop explaining and start asking.

For FLAG_SECURE

, I think yes. It is policy, and root owns the policy. Patch SurfaceFlinger, stop honoring the flag, banking screenshots come back.

Netflix HD is where I run out of road. The frames are in the TEE. Root gets you the kernel, and the kernel is not the thing saying no. So what actually comes out the other end?

I have not tried it. No spare handset to brick.

So has anyone actually done this? Flashaholics, custom ROM people what did you get?

AI agents write code fast. They also silently remove logic, change behavior, and introduce bugs — without telling you. You often find out in production.

git-lrc fixes this. It hooks into git commit and reviews every diff before it lands. 60-second setup. Completely free.

Any feedback or contributors are welcome! It's online, source-available, and ready for anyone to use.

⭐ Star it on GitHub:

| 🇩🇰 Dansk | 🇪🇸 Español | 🇮🇷 Farsi | 🇫🇮 Suomi | 🇯🇵 日本語 | 🇳🇴 Norsk | 🇵🇹 Português | 🇷🇺 Русский | 🇦🇱 Shqip | 🇨🇳 中文 | 🇮🇳 हिन्दी |

GenAI today is a race car without brakes. It accelerates fast -- you describe something, and large blocks of code appear instantly. But AI agents silently break things: they remove logic, relax constraints, introduce expensive cloud calls, leak credentials, and change behavior -- without telling you. You often find out in production.

** git-lrc is your braking system.** It hooks into

git commit

and runs an AI review on every diff In short, git-lrc helps Prevent Outages, Breaches, and Technical Debt Before They Happen

At a glance: 10 risk categories · 100+ failure patterns tracked · every commit…

── more in #artificial-intelligence 4 stories · sorted by recency
── more on @maneshwar 3 stories trending now
sponsored brought to you by zahid.host 4,200+ EU-deployed projects
reading about agents? ship yours in a single git push.

Run your AI side-project on zahid.host

EU-based hosting, git-push deploys, automatic HTTPS, no cold starts. Free tier with a custom domain — perfect for shipping the agent you just read about.

$git push zahid main
Live at https://your-agent.zahid.host
Get free account → Pricing
from €0/mo · no card required
LIVE [news/nobody-painted-that-…] indexed:0 read:5min 2026-07-16 ·