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.
The mental model I had is wrong
Here is what I assumed:
- I press screenshot
- Something detects it
- That something paints black over the protected area
- I get a censored image
Reasonable. Also completely wrong.
Nothing detects anything. Nothing paints anything.
Sit with that, because the rest of this post falls out of it.
Two consumers, two composites
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.
Why it is black, specifically
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.
My bank is doing this too
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.
Netflix is playing an entirely different game
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 |
So does rooting actually work?
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:
HexmosTech
/
git-lrc
Free, Micro AI Code Reviews That Run on Git Commit
| 🇩🇰 Dansk | 🇪🇸 Español | 🇮🇷 Farsi | 🇫🇮 Suomi | 🇯🇵 日本語 | 🇳🇴 Norsk | 🇵🇹 Português | 🇷🇺 Русский | 🇦🇱 Shqip | 🇨🇳 中文 | 🇮🇳 हिन्दी |
git-lrc
Free, Micro AI Code Reviews That Run on Commit
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 before it lands. 60-second setup. Completely free.
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…





Top comments (0)