1 /* 2 * Copyright (C) 2017 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 android.os.strictmode; 18 19 /** Root class for all StrictMode violations. */ 20 public abstract class Violation extends Throwable { 21 private int mHashCode; 22 private boolean mHashCodeValid; 23 Violation(String message)24 Violation(String message) { 25 super(message); 26 } 27 28 @Override hashCode()29 public int hashCode() { 30 synchronized (this) { 31 if (mHashCodeValid) { 32 return mHashCode; 33 } 34 final String message = getMessage(); 35 final Throwable cause = getCause(); 36 int hashCode = message != null ? message.hashCode() : getClass().hashCode(); 37 hashCode = hashCode * 37 + calcStackTraceHashCode(getStackTrace()); 38 hashCode = hashCode * 37 + (cause != null ? cause.toString().hashCode() : 0); 39 mHashCodeValid = true; 40 return mHashCode = hashCode; 41 } 42 } 43 44 @Override initCause(Throwable cause)45 public synchronized Throwable initCause(Throwable cause) { 46 mHashCodeValid = false; 47 return super.initCause(cause); 48 } 49 50 @Override setStackTrace(StackTraceElement[] stackTrace)51 public void setStackTrace(StackTraceElement[] stackTrace) { 52 super.setStackTrace(stackTrace); 53 synchronized (this) { 54 mHashCodeValid = false; 55 } 56 } 57 58 @Override fillInStackTrace()59 public synchronized Throwable fillInStackTrace() { 60 mHashCodeValid = false; 61 return super.fillInStackTrace(); 62 } 63 calcStackTraceHashCode(final StackTraceElement[] stackTrace)64 private static int calcStackTraceHashCode(final StackTraceElement[] stackTrace) { 65 int hashCode = 17; 66 if (stackTrace != null) { 67 for (int i = 0; i < stackTrace.length; i++) { 68 if (stackTrace[i] != null) { 69 hashCode = hashCode * 37 + stackTrace[i].hashCode(); 70 } 71 } 72 } 73 return hashCode; 74 } 75 } 76