1 /* 2 * Copyright (C) 2010 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package dalvik.system; 18 19 import java.io.FileDescriptor; 20 import java.io.FileNotFoundException; 21 import java.io.FileOutputStream; 22 import java.io.IOException; 23 import java.math.BigInteger; 24 import java.net.SocketException; 25 import java.nio.charset.Charsets; 26 27 /** 28 * Mechanism to let threads set restrictions on what code is allowed 29 * to do in their thread. 30 * 31 * <p>This is meant for applications to prevent certain blocking 32 * operations from running on their main event loop (or "UI") threads. 33 * 34 * <p>Note that this is all best-effort to catch most accidental mistakes 35 * and isn't intended to be a perfect mechanism, nor provide any sort of 36 * security. 37 * 38 * @hide 39 */ 40 public final class BlockGuard { 41 42 // TODO: refactor class name to something more generic, since its scope is 43 // growing beyond just blocking/logging. 44 45 public static final int DISALLOW_DISK_WRITE = 0x01; 46 public static final int DISALLOW_DISK_READ = 0x02; 47 public static final int DISALLOW_NETWORK = 0x04; 48 public static final int PASS_RESTRICTIONS_VIA_RPC = 0x08; 49 public static final int PENALTY_LOG = 0x10; 50 public static final int PENALTY_DIALOG = 0x20; 51 public static final int PENALTY_DEATH = 0x40; 52 53 public interface Policy { 54 /** 55 * Called on disk writes. 56 */ 57 void onWriteToDisk(); 58 59 /** 60 * Called on disk reads. 61 */ 62 void onReadFromDisk(); 63 64 /** 65 * Called on network operations. 66 */ 67 void onNetwork(); 68 69 /** 70 * Returns the policy bitmask, for shipping over Binder calls 71 * to remote threads/processes and reinstantiating the policy 72 * there. The bits in the mask are from the DISALLOW_* and 73 * PENALTY_* constants. 74 */ 75 int getPolicyMask(); 76 } 77 78 public static class BlockGuardPolicyException extends RuntimeException { 79 // bitmask of DISALLOW_*, PENALTY_*, etc flags 80 private final int mPolicyState; 81 private final int mPolicyViolated; 82 private final String mMessage; // may be null 83 84 public BlockGuardPolicyException(int policyState, int policyViolated) { 85 this(policyState, policyViolated, null); 86 } 87 88 public BlockGuardPolicyException(int policyState, int policyViolated, String message) { 89 mPolicyState = policyState; 90 mPolicyViolated = policyViolated; 91 mMessage = message; 92 fillInStackTrace(); 93 } 94 95 public int getPolicy() { 96 return mPolicyState; 97 } 98 99 public int getPolicyViolation() { 100 return mPolicyViolated; 101 } 102 103 public String getMessage() { 104 // Note: do not change this format casually. It's 105 // somewhat unfortunately Parceled and passed around 106 // Binder calls and parsed back into an Exception by 107 // Android's StrictMode. This was the least invasive 108 // option and avoided a gross mix of Java Serialization 109 // combined with Parcels. 110 return "policy=" + mPolicyState + " violation=" + mPolicyViolated + 111 (mMessage == null ? "" : (" msg=" + mMessage)); 112 } 113 } 114 115 /** 116 * The default, permissive policy that doesn't prevent any operations. 117 */ 118 public static final Policy LAX_POLICY = new Policy() { 119 public void onWriteToDisk() {} 120 public void onReadFromDisk() {} 121 public void onNetwork() {} 122 public int getPolicyMask() { 123 return 0; 124 } 125 }; 126 127 private static ThreadLocal<Policy> threadPolicy = new ThreadLocal<Policy>() { 128 @Override protected Policy initialValue() { 129 return LAX_POLICY; 130 } 131 }; 132 133 /** 134 * Get the current thread's policy. 135 * 136 * @return the current thread's policy. Never returns null. 137 * Will return the LAX_POLICY instance if nothing else is set. 138 */ 139 public static Policy getThreadPolicy() { 140 return threadPolicy.get(); 141 } 142 143 /** 144 * Sets the current thread's block guard policy. 145 * 146 * @param policy policy to set. May not be null. Use the public LAX_POLICY 147 * if you want to unset the active policy. 148 */ 149 public static void setThreadPolicy(Policy policy) { 150 if (policy == null) { 151 throw new NullPointerException("policy == null"); 152 } 153 threadPolicy.set(policy); 154 } 155 156 private BlockGuard() {} 157 } 158