diff options
Diffstat (limited to 'core/java/android/os')
-rw-r--r-- | core/java/android/os/FileUtils.java | 7 | ||||
-rw-r--r-- | core/java/android/os/StrictMode.java | 78 |
2 files changed, 73 insertions, 12 deletions
diff --git a/core/java/android/os/FileUtils.java b/core/java/android/os/FileUtils.java index 9d50fd9..f56f6a9 100644 --- a/core/java/android/os/FileUtils.java +++ b/core/java/android/os/FileUtils.java @@ -76,7 +76,12 @@ public class FileUtils * @return true if the file exists and false if it does not exist. If you do not have * permission to stat the file, then this method will return false. */ - public static native boolean getFileStatus(String path, FileStatus status); + public static boolean getFileStatus(String path, FileStatus status) { + StrictMode.noteDiskRead(); + return getFileStatusNative(path, status); + } + + private static native boolean getFileStatusNative(String path, FileStatus status); /** Regular expression for safe filenames: no spaces or metacharacters */ private static final Pattern SAFE_FILENAME_PATTERN = Pattern.compile("[\\w%+,./=_-]+"); diff --git a/core/java/android/os/StrictMode.java b/core/java/android/os/StrictMode.java index b00b9c9..e314fce 100644 --- a/core/java/android/os/StrictMode.java +++ b/core/java/android/os/StrictMode.java @@ -669,25 +669,46 @@ public final class StrictMode { CloseGuard.setEnabled(enabled); } - private static class StrictModeNetworkViolation extends BlockGuard.BlockGuardPolicyException { + /** + * @hide + */ + public static class StrictModeViolation extends BlockGuard.BlockGuardPolicyException { + public StrictModeViolation(int policyState, int policyViolated, String message) { + super(policyState, policyViolated, message); + } + } + + /** + * @hide + */ + public static class StrictModeNetworkViolation extends StrictModeViolation { public StrictModeNetworkViolation(int policyMask) { - super(policyMask, DETECT_NETWORK); + super(policyMask, DETECT_NETWORK, null); } } - private static class StrictModeDiskReadViolation extends BlockGuard.BlockGuardPolicyException { + /** + * @hide + */ + private static class StrictModeDiskReadViolation extends StrictModeViolation { public StrictModeDiskReadViolation(int policyMask) { - super(policyMask, DETECT_DISK_READ); + super(policyMask, DETECT_DISK_READ, null); } } - private static class StrictModeDiskWriteViolation extends BlockGuard.BlockGuardPolicyException { + /** + * @hide + */ + private static class StrictModeDiskWriteViolation extends StrictModeViolation { public StrictModeDiskWriteViolation(int policyMask) { - super(policyMask, DETECT_DISK_WRITE); + super(policyMask, DETECT_DISK_WRITE, null); } } - private static class StrictModeCustomViolation extends BlockGuard.BlockGuardPolicyException { + /** + * @hide + */ + private static class StrictModeCustomViolation extends StrictModeViolation { public StrictModeCustomViolation(int policyMask, String name) { super(policyMask, DETECT_CUSTOM, name); } @@ -1007,9 +1028,16 @@ public final class StrictMode { // thread, in "gather" mode. In this case, the duration // of the violation is computed by the ultimate caller and // its Looper, if any. + // + // Also, as a special short-cut case when the only penalty + // bit is death, we die immediately, rather than timing + // the violation's duration. This makes it convenient to + // use in unit tests too, rather than waiting on a Looper. + // // TODO: if in gather mode, ignore Looper.myLooper() and always // go into this immediate mode? - if (looper == null) { + if (looper == null || + (info.policy & PENALTY_MASK) == PENALTY_DEATH) { info.durationMillis = -1; // unknown (redundant, already set) handleViolation(info); return; @@ -1179,13 +1207,16 @@ public final class StrictMode { } if ((info.policy & PENALTY_DEATH) != 0) { - System.err.println("StrictMode policy violation with POLICY_DEATH; shutting down."); - Process.killProcess(Process.myPid()); - System.exit(10); + executeDeathPenalty(info); } } } + private static void executeDeathPenalty(ViolationInfo info) { + int violationBit = parseViolationFromMessage(info.crashInfo.exceptionMessage); + throw new StrictModeViolation(info.policy, violationBit, null); + } + /** * In the common case, as set by conditionallyEnableDebugLogging, * we're just dropboxing any violations but not showing a dialog, @@ -1597,6 +1628,31 @@ public final class StrictMode { } /** + * @hide + */ + public static void noteDiskRead() { + BlockGuard.Policy policy = BlockGuard.getThreadPolicy(); + Log.d(TAG, "noteDiskRead; policy=" + policy); + if (!(policy instanceof AndroidBlockGuardPolicy)) { + // StrictMode not enabled. + return; + } + ((AndroidBlockGuardPolicy) policy).onReadFromDisk(); + } + + /** + * @hide + */ + public static void noteDiskWrite() { + BlockGuard.Policy policy = BlockGuard.getThreadPolicy(); + if (!(policy instanceof AndroidBlockGuardPolicy)) { + // StrictMode not enabled. + return; + } + ((AndroidBlockGuardPolicy) policy).onWriteToDisk(); + } + + /** * Parcelable that gets sent in Binder call headers back to callers * to report violations that happened during a cross-process call. * |