summaryrefslogtreecommitdiff
path: root/dalvik/src/main/java/dalvik/system/BlockGuard.java
diff options
context:
space:
mode:
Diffstat (limited to 'dalvik/src/main/java/dalvik/system/BlockGuard.java')
-rw-r--r--dalvik/src/main/java/dalvik/system/BlockGuard.java157
1 files changed, 157 insertions, 0 deletions
diff --git a/dalvik/src/main/java/dalvik/system/BlockGuard.java b/dalvik/src/main/java/dalvik/system/BlockGuard.java
new file mode 100644
index 0000000..d61f0e1
--- /dev/null
+++ b/dalvik/src/main/java/dalvik/system/BlockGuard.java
@@ -0,0 +1,157 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package dalvik.system;
+
+import java.io.FileDescriptor;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.math.BigInteger;
+import java.net.SocketException;
+import java.nio.charset.Charsets;
+
+/**
+ * Mechanism to let threads set restrictions on what code is allowed
+ * to do in their thread.
+ *
+ * <p>This is meant for applications to prevent certain blocking
+ * operations from running on their main event loop (or "UI") threads.
+ *
+ * <p>Note that this is all best-effort to catch most accidental mistakes
+ * and isn't intended to be a perfect mechanism, nor provide any sort of
+ * security.
+ *
+ * @hide
+ */
+public final class BlockGuard {
+
+ // TODO: refactor class name to something more generic, since its scope is
+ // growing beyond just blocking/logging.
+
+ public static final int DISALLOW_DISK_WRITE = 0x01;
+ public static final int DISALLOW_DISK_READ = 0x02;
+ public static final int DISALLOW_NETWORK = 0x04;
+ public static final int PASS_RESTRICTIONS_VIA_RPC = 0x08;
+ public static final int PENALTY_LOG = 0x10;
+ public static final int PENALTY_DIALOG = 0x20;
+ public static final int PENALTY_DEATH = 0x40;
+
+ public interface Policy {
+ /**
+ * Called on disk writes.
+ */
+ void onWriteToDisk();
+
+ /**
+ * Called on disk reads.
+ */
+ void onReadFromDisk();
+
+ /**
+ * Called on network operations.
+ */
+ void onNetwork();
+
+ /**
+ * Returns the policy bitmask, for shipping over Binder calls
+ * to remote threads/processes and reinstantiating the policy
+ * there. The bits in the mask are from the DISALLOW_* and
+ * PENALTY_* constants.
+ */
+ int getPolicyMask();
+ }
+
+ public static class BlockGuardPolicyException extends RuntimeException {
+ // bitmask of DISALLOW_*, PENALTY_*, etc flags
+ private final int mPolicyState;
+ private final int mPolicyViolated;
+ private final String mMessage; // may be null
+
+ public BlockGuardPolicyException(int policyState, int policyViolated) {
+ this(policyState, policyViolated, null);
+ }
+
+ public BlockGuardPolicyException(int policyState, int policyViolated, String message) {
+ mPolicyState = policyState;
+ mPolicyViolated = policyViolated;
+ mMessage = message;
+ fillInStackTrace();
+ }
+
+ public int getPolicy() {
+ return mPolicyState;
+ }
+
+ public int getPolicyViolation() {
+ return mPolicyViolated;
+ }
+
+ public String getMessage() {
+ // Note: do not change this format casually. It's
+ // somewhat unfortunately Parceled and passed around
+ // Binder calls and parsed back into an Exception by
+ // Android's StrictMode. This was the least invasive
+ // option and avoided a gross mix of Java Serialization
+ // combined with Parcels.
+ return "policy=" + mPolicyState + " violation=" + mPolicyViolated +
+ (mMessage == null ? "" : (" msg=" + mMessage));
+ }
+ }
+
+ /**
+ * The default, permissive policy that doesn't prevent any operations.
+ */
+ public static final Policy LAX_POLICY = new Policy() {
+ public void onWriteToDisk() {}
+ public void onReadFromDisk() {}
+ public void onNetwork() {}
+ public int getPolicyMask() {
+ return 0;
+ }
+ };
+
+ private static ThreadLocal<Policy> threadPolicy = new ThreadLocal<Policy>() {
+ @Override protected Policy initialValue() {
+ return LAX_POLICY;
+ }
+ };
+
+ /**
+ * Get the current thread's policy.
+ *
+ * @return the current thread's policy. Never returns null.
+ * Will return the LAX_POLICY instance if nothing else is set.
+ */
+ public static Policy getThreadPolicy() {
+ return threadPolicy.get();
+ }
+
+ /**
+ * Sets the current thread's block guard policy.
+ *
+ * @param policy policy to set. May not be null. Use the public LAX_POLICY
+ * if you want to unset the active policy.
+ */
+ public static void setThreadPolicy(Policy policy) {
+ if (policy == null) {
+ throw new NullPointerException("policy == null");
+ }
+ threadPolicy.set(policy);
+ }
+
+ private BlockGuard() {}
+}