MessageDigest.java revision 897538a36c18f4db8f9f68ee566aec0bda842e9f
1adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project/* 2adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Licensed to the Apache Software Foundation (ASF) under one or more 3adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * contributor license agreements. See the NOTICE file distributed with 4adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * this work for additional information regarding copyright ownership. 5adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * The ASF licenses this file to You under the Apache License, Version 2.0 6adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * (the "License"); you may not use this file except in compliance with 7adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the License. You may obtain a copy of the License at 8adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * 9adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * http://www.apache.org/licenses/LICENSE-2.0 10adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * 11adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Unless required by applicable law or agreed to in writing, software 12adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS, 13adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * See the License for the specific language governing permissions and 15adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * limitations under the License. 16adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 17adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 18adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectpackage java.security; 19adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 20adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport java.nio.ByteBuffer; 21adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 22adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport org.apache.harmony.security.fortress.Engine; 23adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 24adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project/** 25adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * {@code MessageDigest} is an engine class which is capable of generating one 26adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * way hash values for arbitrary input, utilizing the algorithm it was 27adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * initialized with. 282f9e468ed4985edfd5e351faf2089d91e561e41dElliott Hughes * 29adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @see MessageDigestSpi 30adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 31adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectpublic abstract class MessageDigest extends MessageDigestSpi { 322f9e468ed4985edfd5e351faf2089d91e561e41dElliott Hughes 33adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // The service name 34f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes private static final String SERVICE = "MessageDigest"; 35adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 36adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // Used to access common engine functionality 37adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project private static Engine engine = new Engine(SERVICE); 38adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 39adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // The provider 40adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project private Provider provider; 41adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 42adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // The algorithm. 43adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project private String algorithm; 44adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 45adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 46adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Constructs a new instance of {@code MessageDigest} with the name of 47adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the algorithm to use. 48f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes * 49adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param algorithm 50adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the name of algorithm to use 51adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 52adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project protected MessageDigest(String algorithm) { 53adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project this.algorithm = algorithm; 54adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 55adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 56adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 57adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Returns a new instance of {@code MessageDigest} that utilizes the 58adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * specified algorithm. 59f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes * 60adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param algorithm 61adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the name of the algorithm to use 62adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @return a new instance of {@code MessageDigest} that utilizes the 63adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * specified algorithm 64adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws NoSuchAlgorithmException 65adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * if the specified algorithm is not available 66adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws NullPointerException 67adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * if {@code algorithm} is {@code null} 68adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 69adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public static MessageDigest getInstance(String algorithm) 70adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project throws NoSuchAlgorithmException { 71adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (algorithm == null) { 72897538a36c18f4db8f9f68ee566aec0bda842e9fElliott Hughes throw new NullPointerException(); 73adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 74adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project MessageDigest result; 75adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project synchronized (engine) { 76adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project engine.getInstance(algorithm, null); 77adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (engine.spi instanceof MessageDigest) { 78adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project result = (MessageDigest) engine.spi; 79adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project result.algorithm = algorithm; 80adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project result.provider = engine.provider; 81adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return result; 82adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 832f9e468ed4985edfd5e351faf2089d91e561e41dElliott Hughes return new MessageDigestImpl((MessageDigestSpi) engine.spi, 842f9e468ed4985edfd5e351faf2089d91e561e41dElliott Hughes engine.provider, algorithm); 85adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 86adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 87adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 88adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 89adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Returns a new instance of {@code MessageDigest} that utilizes the 90adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * specified algorithm from the specified provider. 91f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes * 92adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param algorithm 93adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the name of the algorithm to use 94adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param provider 95adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the name of the provider 96adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @return a new instance of {@code MessageDigest} that utilizes the 97adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * specified algorithm from the specified provider 98adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws NoSuchAlgorithmException 99adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * if the specified algorithm is not available 100adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws NoSuchProviderException 101adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * if the specified provider is not available 102adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws NullPointerException 103adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * if {@code algorithm} is {@code null} 104897538a36c18f4db8f9f68ee566aec0bda842e9fElliott Hughes * @throws IllegalArgumentException if {@code provider == null || provider.isEmpty()} 105adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 106adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public static MessageDigest getInstance(String algorithm, String provider) 107adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project throws NoSuchAlgorithmException, NoSuchProviderException { 108897538a36c18f4db8f9f68ee566aec0bda842e9fElliott Hughes if (provider == null || provider.isEmpty()) { 109897538a36c18f4db8f9f68ee566aec0bda842e9fElliott Hughes throw new IllegalArgumentException(); 110adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 111adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project Provider p = Security.getProvider(provider); 112adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (p == null) { 113897538a36c18f4db8f9f68ee566aec0bda842e9fElliott Hughes throw new NoSuchProviderException(provider); 114adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 115adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return getInstance(algorithm, p); 116adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 117adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 118adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 119adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Returns a new instance of {@code MessageDigest} that utilizes the 120adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * specified algorithm from the specified provider. 121f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes * 122adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param algorithm 123adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the name of the algorithm to use 124adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param provider 125adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the provider 126adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @return a new instance of {@code MessageDigest} that utilizes the 127adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * specified algorithm from the specified provider 128adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws NoSuchAlgorithmException 129adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * if the specified algorithm is not available 130adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws NullPointerException 131adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * if {@code algorithm} is {@code null} 132897538a36c18f4db8f9f68ee566aec0bda842e9fElliott Hughes * @throws IllegalArgumentException if {@code provider == null} 133adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 134adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public static MessageDigest getInstance(String algorithm, Provider provider) 135adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project throws NoSuchAlgorithmException { 136adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (provider == null) { 137897538a36c18f4db8f9f68ee566aec0bda842e9fElliott Hughes throw new IllegalArgumentException(); 138adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 139adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (algorithm == null) { 140897538a36c18f4db8f9f68ee566aec0bda842e9fElliott Hughes throw new NullPointerException(); 141adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 142adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project MessageDigest result; 143adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project synchronized (engine) { 144adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project engine.getInstance(algorithm, provider, null); 145adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (engine.spi instanceof MessageDigest) { 146adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project result = (MessageDigest) engine.spi; 147adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project result.algorithm = algorithm; 148adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project result.provider = provider; 149adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return result; 150adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 1512f9e468ed4985edfd5e351faf2089d91e561e41dElliott Hughes result = new MessageDigestImpl((MessageDigestSpi) engine.spi, 1522f9e468ed4985edfd5e351faf2089d91e561e41dElliott Hughes provider, algorithm); 1532f9e468ed4985edfd5e351faf2089d91e561e41dElliott Hughes return result; 154adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 155adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 156adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 157adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 158adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Puts this {@code MessageDigest} back in an initial state, such that it is 159adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * ready to compute a one way hash value. 160adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 161adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public void reset() { 162adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project engineReset(); 163adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 164adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 165adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 166adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Updates this {@code MessageDigest} using the given {@code byte}. 167f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes * 168adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param arg0 169adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the {@code byte} to update this {@code MessageDigest} with 170adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @see #reset() 171adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 172adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public void update(byte arg0) { 173adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project engineUpdate(arg0); 174adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 175adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 176adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 177adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Updates this {@code MessageDigest} using the given {@code byte[]}. 178f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes * 179adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param input 180adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the {@code byte} array 181adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param offset 182adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the index of the first byte in {@code input} to update from 183adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param len 184adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the number of bytes in {@code input} to update from 185adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws IllegalArgumentException 186adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * if {@code offset} or {@code len} are not valid in respect to 187adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * {@code input} 188adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 189adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public void update(byte[] input, int offset, int len) { 190adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (input == null || 1912f9e468ed4985edfd5e351faf2089d91e561e41dElliott Hughes // offset < 0 || len < 0 || 192adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // checks for negative values are commented out intentionally 193adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // see HARMONY-1120 for details 194adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project (long) offset + (long) len > input.length) { 195897538a36c18f4db8f9f68ee566aec0bda842e9fElliott Hughes throw new IllegalArgumentException(); 196adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 197adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project engineUpdate(input, offset, len); 198adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 199adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 200adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 201adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Updates this {@code MessageDigest} using the given {@code byte[]}. 202f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes * 203adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param input 204adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the {@code byte} array 205adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws NullPointerException 206adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * if {@code input} is {@code null} 207adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 208adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public void update(byte[] input) { 209adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (input == null) { 210897538a36c18f4db8f9f68ee566aec0bda842e9fElliott Hughes throw new NullPointerException(); 211adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 212adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project engineUpdate(input, 0, input.length); 213adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 214adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 215adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 216adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Computes and returns the final hash value for this {@link MessageDigest}. 217adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * After the digest is computed the receiver is reset. 218f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes * 219adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @return the computed one way hash value 220adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @see #reset 221adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 222adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public byte[] digest() { 223adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return engineDigest(); 224adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 225adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 226adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 227adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Computes and stores the final hash value for this {@link MessageDigest}. 228adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * After the digest is computed the receiver is reset. 229f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes * 230adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param buf 231adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the buffer to store the result 232adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param offset 233adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the index of the first byte in {@code buf} to store 234adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param len 235adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the number of bytes allocated for the digest 236adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @return the number of bytes written to {@code buf} 237adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws DigestException 238adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * if an error occures 239adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws IllegalArgumentException 240adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * if {@code offset} or {@code len} are not valid in respect to 241adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * {@code buf} 242adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @see #reset() 243adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 244adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public int digest(byte[] buf, int offset, int len) throws DigestException { 245adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (buf == null || 2462f9e468ed4985edfd5e351faf2089d91e561e41dElliott Hughes // offset < 0 || len < 0 || 247adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // checks for negative values are commented out intentionally 248adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // see HARMONY-1148 for details 249adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project (long) offset + (long) len > buf.length) { 250897538a36c18f4db8f9f68ee566aec0bda842e9fElliott Hughes throw new IllegalArgumentException(); 251adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 252adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return engineDigest(buf, offset, len); 253adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 254adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 255adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 256adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Performs the final update and then computes and returns the final hash 257adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * value for this {@link MessageDigest}. After the digest is computed the 258adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * receiver is reset. 259f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes * 260adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param input 261adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the {@code byte} array 262adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @return the computed one way hash value 263adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @see #reset() 264adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 265adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public byte[] digest(byte[] input) { 266adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project update(input); 267adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return digest(); 268adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 269adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 270adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 271adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Returns a string containing a concise, human-readable description of this 272adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * {@code MessageDigest} including the name of its algorithm. 273f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes * 274adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @return a printable representation for this {@code MessageDigest} 275adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 2762f9e468ed4985edfd5e351faf2089d91e561e41dElliott Hughes @Override 277adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public String toString() { 278f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes return "MESSAGE DIGEST " + algorithm; 279adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 280adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 281adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 282adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Indicates whether to digest are equal by performing a simply 283adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * byte-per-byte compare of the two digests. 284f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes * 285adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param digesta 286adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the first digest to be compared 287adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param digestb 288adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the second digest to be compared 289adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @return {@code true} if the two hashes are equal, {@code false} otherwise 290adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 291adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public static boolean isEqual(byte[] digesta, byte[] digestb) { 292adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (digesta.length != digestb.length) { 293adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return false; 294adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 295adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project for (int i = 0; i < digesta.length; i++) { 296adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (digesta[i] != digestb[i]) { 297adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return false; 298adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 299adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 300adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return true; 301adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 302adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 303adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 304adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Returns the name of the algorithm of this {@code MessageDigest}. 305f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes * 306adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @return the name of the algorithm of this {@code MessageDigest} 307adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 308adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public final String getAlgorithm() { 309adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return algorithm; 310adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 311adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 312adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 313adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Returns the provider associated with this {@code MessageDigest}. 314f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes * 315adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @return the provider associated with this {@code MessageDigest} 316adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 317adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public final Provider getProvider() { 318adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return provider; 319adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 320adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 321adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 322adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Returns the engine digest length in bytes. If the implementation does not 323adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * implement this function or is not an instance of {@code Cloneable}, 324adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * {@code 0} is returned. 325f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes * 326adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @return the digest length in bytes, or {@code 0} 327adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 328adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public final int getDigestLength() { 329adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project int l = engineGetDigestLength(); 330adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (l != 0) { 331adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return l; 332adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 333adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (!(this instanceof Cloneable)) { 334adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return 0; 335adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 336adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project try { 337adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project MessageDigest md = (MessageDigest) clone(); 338adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return md.digest().length; 339adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } catch (CloneNotSupportedException e) { 340adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return 0; 341adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 342adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 343adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 3442f9e468ed4985edfd5e351faf2089d91e561e41dElliott Hughes @Override 345adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public Object clone() throws CloneNotSupportedException { 346adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (this instanceof Cloneable) { 347adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return super.clone(); 348adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 3492f9e468ed4985edfd5e351faf2089d91e561e41dElliott Hughes throw new CloneNotSupportedException(); 350adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 351adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 352adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 353adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Updates this {@code MessageDigest} using the given {@code input}. 354f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes * 355adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param input 356adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the {@code ByteBuffer} 357adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 358adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public final void update(ByteBuffer input) { 359adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project engineUpdate(input); 360adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 361adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 362adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 363f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes * 364adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * The internal MessageDigest implementation 365f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes * 366adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 367adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project private static class MessageDigestImpl extends MessageDigest { 3682f9e468ed4985edfd5e351faf2089d91e561e41dElliott Hughes 369adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // MessageDigestSpi implementation 370adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project private MessageDigestSpi spiImpl; 371adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 372adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // MessageDigestImpl ctor 373adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project private MessageDigestImpl(MessageDigestSpi messageDigestSpi, 374adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project Provider provider, String algorithm) { 375adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project super(algorithm); 376adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project super.provider = provider; 377adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project spiImpl = messageDigestSpi; 378adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 379adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 380adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // engineReset() implementation 3812f9e468ed4985edfd5e351faf2089d91e561e41dElliott Hughes @Override 382adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project protected void engineReset() { 383adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project spiImpl.engineReset(); 384adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 385adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 386adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // engineDigest() implementation 3872f9e468ed4985edfd5e351faf2089d91e561e41dElliott Hughes @Override 388adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project protected byte[] engineDigest() { 389adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return spiImpl.engineDigest(); 390adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 391adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 392adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // engineGetDigestLength() implementation 3932f9e468ed4985edfd5e351faf2089d91e561e41dElliott Hughes @Override 394adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project protected int engineGetDigestLength() { 395adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return spiImpl.engineGetDigestLength(); 396adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 397adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 398adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // engineUpdate() implementation 3992f9e468ed4985edfd5e351faf2089d91e561e41dElliott Hughes @Override 400adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project protected void engineUpdate(byte arg0) { 401adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project spiImpl.engineUpdate(arg0); 402adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 403adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 404adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // engineUpdate() implementation 4052f9e468ed4985edfd5e351faf2089d91e561e41dElliott Hughes @Override 406adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project protected void engineUpdate(byte[] arg0, int arg1, int arg2) { 407adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project spiImpl.engineUpdate(arg0, arg1, arg2); 408adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 409adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 410adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // Returns a clone if the spiImpl is cloneable 4112f9e468ed4985edfd5e351faf2089d91e561e41dElliott Hughes @Override 412adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public Object clone() throws CloneNotSupportedException { 413adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (spiImpl instanceof Cloneable) { 414adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project MessageDigestSpi spi = (MessageDigestSpi) spiImpl.clone(); 415adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return new MessageDigestImpl(spi, getProvider(), getAlgorithm()); 416adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 417f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes 4182f9e468ed4985edfd5e351faf2089d91e561e41dElliott Hughes throw new CloneNotSupportedException(); 419adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 420adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 421adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project} 422