From c95b2c85f3101e686c08d0f0e117088a524894c7 Mon Sep 17 00:00:00 2001 From: Shubham Ajmera Date: Thu, 29 Sep 2016 16:35:36 +0100 Subject: [PATCH] Add new StrictMode thread policy - DETECT_UNBUFFERED_IO This will enable the developers to check if they could replace an unbuffered I/O operation with a corresponding buffered I/O operation. The policy can be set as follow: StrictMode.setThreadPolicy(new StrictMode.ThreadPolicy.Builder() .detectUnbufferedIO().build()); Test: vogar BlockGuardTest Bug: 3018772 Change-Id: Ib804a8e9980ae40abfd216f8b87c250fd413bd5c (cherry picked from commit 9b7184a8fd6c940872f1526667dd7933db4bdd5f)w --- api/current.txt | 2 + api/system-current.txt | 2 + api/test-current.txt | 2 + core/java/android/os/StrictMode.java | 56 +++++++++++++++++++++++++++- 4 files changed, 61 insertions(+), 1 deletion(-) diff --git a/api/current.txt b/api/current.txt index 125e11311b203..3a37e630475eb 100644 --- a/api/current.txt +++ b/api/current.txt @@ -29169,6 +29169,7 @@ package android.os { method public android.os.StrictMode.ThreadPolicy.Builder detectDiskWrites(); method public android.os.StrictMode.ThreadPolicy.Builder detectNetwork(); method public android.os.StrictMode.ThreadPolicy.Builder detectResourceMismatches(); + method public android.os.StrictMode.ThreadPolicy.Builder detectUnbufferedIo(); method public android.os.StrictMode.ThreadPolicy.Builder penaltyDeath(); method public android.os.StrictMode.ThreadPolicy.Builder penaltyDeathOnNetwork(); method public android.os.StrictMode.ThreadPolicy.Builder penaltyDialog(); @@ -29181,6 +29182,7 @@ package android.os { method public android.os.StrictMode.ThreadPolicy.Builder permitDiskWrites(); method public android.os.StrictMode.ThreadPolicy.Builder permitNetwork(); method public android.os.StrictMode.ThreadPolicy.Builder permitResourceMismatches(); + method public android.os.StrictMode.ThreadPolicy.Builder permitUnbufferedIo(); } public static final class StrictMode.VmPolicy { diff --git a/api/system-current.txt b/api/system-current.txt index 6dc2bcf5d9e1d..6dba2c9c89fd6 100644 --- a/api/system-current.txt +++ b/api/system-current.txt @@ -31637,6 +31637,7 @@ package android.os { method public android.os.StrictMode.ThreadPolicy.Builder detectDiskWrites(); method public android.os.StrictMode.ThreadPolicy.Builder detectNetwork(); method public android.os.StrictMode.ThreadPolicy.Builder detectResourceMismatches(); + method public android.os.StrictMode.ThreadPolicy.Builder detectUnbufferedIo(); method public android.os.StrictMode.ThreadPolicy.Builder penaltyDeath(); method public android.os.StrictMode.ThreadPolicy.Builder penaltyDeathOnNetwork(); method public android.os.StrictMode.ThreadPolicy.Builder penaltyDialog(); @@ -31649,6 +31650,7 @@ package android.os { method public android.os.StrictMode.ThreadPolicy.Builder permitDiskWrites(); method public android.os.StrictMode.ThreadPolicy.Builder permitNetwork(); method public android.os.StrictMode.ThreadPolicy.Builder permitResourceMismatches(); + method public android.os.StrictMode.ThreadPolicy.Builder permitUnbufferedIo(); } public static final class StrictMode.VmPolicy { diff --git a/api/test-current.txt b/api/test-current.txt index 941790e11c01e..ca62c57d7b337 100644 --- a/api/test-current.txt +++ b/api/test-current.txt @@ -29238,6 +29238,7 @@ package android.os { method public android.os.StrictMode.ThreadPolicy.Builder detectDiskWrites(); method public android.os.StrictMode.ThreadPolicy.Builder detectNetwork(); method public android.os.StrictMode.ThreadPolicy.Builder detectResourceMismatches(); + method public android.os.StrictMode.ThreadPolicy.Builder detectUnbufferedIo(); method public android.os.StrictMode.ThreadPolicy.Builder penaltyDeath(); method public android.os.StrictMode.ThreadPolicy.Builder penaltyDeathOnNetwork(); method public android.os.StrictMode.ThreadPolicy.Builder penaltyDialog(); @@ -29250,6 +29251,7 @@ package android.os { method public android.os.StrictMode.ThreadPolicy.Builder permitDiskWrites(); method public android.os.StrictMode.ThreadPolicy.Builder permitNetwork(); method public android.os.StrictMode.ThreadPolicy.Builder permitResourceMismatches(); + method public android.os.StrictMode.ThreadPolicy.Builder permitUnbufferedIo(); } public static final class StrictMode.VmPolicy { diff --git a/core/java/android/os/StrictMode.java b/core/java/android/os/StrictMode.java index c36b48886f370..ff69cf6a94bce 100644 --- a/core/java/android/os/StrictMode.java +++ b/core/java/android/os/StrictMode.java @@ -191,9 +191,14 @@ public final class StrictMode { */ public static final int DETECT_RESOURCE_MISMATCH = 0x10; // for ThreadPolicy + /** + * @hide + */ + public static final int DETECT_UNBUFFERED_IO = 0x20; // for ThreadPolicy + private static final int ALL_THREAD_DETECT_BITS = DETECT_DISK_WRITE | DETECT_DISK_READ | DETECT_NETWORK | DETECT_CUSTOM | - DETECT_RESOURCE_MISMATCH; + DETECT_RESOURCE_MISMATCH | DETECT_UNBUFFERED_IO; // Byte 2: Process-policy @@ -464,6 +469,20 @@ public final class StrictMode { return disable(DETECT_RESOURCE_MISMATCH); } + /** + * Detect unbuffered input/output operations. + */ + public Builder detectUnbufferedIo() { + return enable(DETECT_UNBUFFERED_IO); + } + + /** + * Detect unbuffered input/output operations. + */ + public Builder permitUnbufferedIo() { + return disable(DETECT_UNBUFFERED_IO); + } + /** * Enables detection of mismatches between defined resource types * and getter calls. @@ -973,6 +992,15 @@ public final class StrictMode { } } + /** + * @hide + */ + private static class StrictModeUnbufferedIOViolation extends StrictModeViolation { + public StrictModeUnbufferedIOViolation(int policyMask) { + super(policyMask, DETECT_UNBUFFERED_IO, null); + } + } + /** * Returns the bitmask of the current thread's policy. * @@ -1281,6 +1309,20 @@ public final class StrictMode { startHandlingViolationException(e); } + // Part of BlockGuard.Policy; just part of StrictMode: + public void onUnbufferedIO() { + if ((mPolicyMask & DETECT_UNBUFFERED_IO) == 0) { + return; + } + if (tooManyViolationsThisLoop()) { + return; + } + BlockGuard.BlockGuardPolicyException e = + new StrictModeUnbufferedIOViolation(mPolicyMask); + e.fillInStackTrace(); + startHandlingViolationException(e); + } + // Part of BlockGuard.Policy interface: public void onReadFromDisk() { if ((mPolicyMask & DETECT_DISK_READ) == 0) { @@ -2205,6 +2247,18 @@ public final class StrictMode { ((AndroidBlockGuardPolicy) policy).onResourceMismatch(tag); } + /** + * @hide + */ + public static void noteUnbufferedIO() { + BlockGuard.Policy policy = BlockGuard.getThreadPolicy(); + if (!(policy instanceof AndroidBlockGuardPolicy)) { + // StrictMode not enabled. + return; + } + ((AndroidBlockGuardPolicy) policy).onUnbufferedIO(); + } + /** * @hide */