Skip to content

Instantly share code, notes, and snippets.

@gwpantazes
Created November 2, 2017 20:53
Show Gist options
  • Save gwpantazes/fd1966aaa4e857cddaa2b3ea4a53a91f to your computer and use it in GitHub Desktop.
Save gwpantazes/fd1966aaa4e857cddaa2b3ea4a53a91f to your computer and use it in GitHub Desktop.
isAnyScreenLayerSecure() Android secure screen detection
import org.apache.commons.io.IOUtils;
import se.vidstige.jadb.JadbDevice;
import se.vidstige.jadb.JadbException;
import java.io.IOException;
import java.io.InputStream;
import java.math.BigInteger;
import java.nio.charset.Charset;
private static final int FLAG_SECURE_BITMASK = 0x2000;
private static final int BASE_HEX = 16;
/**
* Checks whether any layer on screen is secure.
*
* @param device An Android Device
* @return If any layer on screen is secure
* @throws IOException If the stream processing fails
* @throws JadbException If working with the device fails
* @see <a href="https://stackoverflow.com/a/45952980/2291928">
* How to query FLAG_SECURE from current APK screen via command line?</a>
* <p>
* You can find out if some specific window has the FLAG_SECURE set
* by checking mAttr line in the {@code dumpsys window <window id>}
* <p><pre>
* {@code
* $ dumpsys window com.android.settings | grep 'mAttrs='
* > mAttrs=WM.LayoutParams{(0,0)(fillxfill) sim=#20 ty=1 fl=#85810100 pfl=0x20000 wanim=0x103046a vsysui=0x700 needsMenuKey=2}
* }
* </pre>
* <p>
* The fl= value is the WindowManager.LayoutParams().flags of that window in hex.
* FLAG_SECURE is a bitmask with the value of 0x2000. This is how you can check it right in the adb shell:
* {@code for f in $(dumpsys window com.android.settings | grep 'mAttrs=' | grep -o ' fl=#[^ ]*'); do [[ $((16#${f#*#}&8192)) -ne 0 ]] && echo 'FLAG_SECURE is set' || echo 'FLAG_SECURE is not set'; done}
*/
public static boolean isAnyScreenLayerSecure(JadbDevice device) throws IOException, JadbException
{
InputStream inputStream = device.executeShell("dumpsys window | grep 'mAttrs=' | grep -o ' fl=#[^ ]*'");
for (String flag : IOUtils.readLines(inputStream, Charset.defaultCharset()))
{
flag = flag.split("#")[1];
BigInteger maskedFlag = new BigInteger(flag, BASE_HEX).and(BigInteger.valueOf(FLAG_SECURE_BITMASK));
if (!maskedFlag.equals(BigInteger.ZERO))
{
return true;
}
}
return false;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment