19182d3c4eb1f9065cb33df5a3594969dd0d42accMike Lockwood/* 29182d3c4eb1f9065cb33df5a3594969dd0d42accMike Lockwood * Copyright (C) 2011 The Android Open Source Project 39182d3c4eb1f9065cb33df5a3594969dd0d42accMike Lockwood * 49182d3c4eb1f9065cb33df5a3594969dd0d42accMike Lockwood * Licensed under the Apache License, Version 2.0 (the "License"); 59182d3c4eb1f9065cb33df5a3594969dd0d42accMike Lockwood * you may not use this file except in compliance with the License. 69182d3c4eb1f9065cb33df5a3594969dd0d42accMike Lockwood * You may obtain a copy of the License at 79182d3c4eb1f9065cb33df5a3594969dd0d42accMike Lockwood * 89182d3c4eb1f9065cb33df5a3594969dd0d42accMike Lockwood * http://www.apache.org/licenses/LICENSE-2.0 99182d3c4eb1f9065cb33df5a3594969dd0d42accMike Lockwood * 109182d3c4eb1f9065cb33df5a3594969dd0d42accMike Lockwood * Unless required by applicable law or agreed to in writing, software 119182d3c4eb1f9065cb33df5a3594969dd0d42accMike Lockwood * distributed under the License is distributed on an "AS IS" BASIS, 129182d3c4eb1f9065cb33df5a3594969dd0d42accMike Lockwood * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 139182d3c4eb1f9065cb33df5a3594969dd0d42accMike Lockwood * See the License for the specific language governing permissions and 149182d3c4eb1f9065cb33df5a3594969dd0d42accMike Lockwood * limitations under the License. 159182d3c4eb1f9065cb33df5a3594969dd0d42accMike Lockwood */ 169182d3c4eb1f9065cb33df5a3594969dd0d42accMike Lockwood 17c4308f01c965571dc2354107c3574df113e397eeMike Lockwoodpackage android.hardware.usb; 189182d3c4eb1f9065cb33df5a3594969dd0d42accMike Lockwood 199182d3c4eb1f9065cb33df5a3594969dd0d42accMike Lockwoodimport android.os.Bundle; 209182d3c4eb1f9065cb33df5a3594969dd0d42accMike Lockwoodimport android.os.Parcel; 219182d3c4eb1f9065cb33df5a3594969dd0d42accMike Lockwoodimport android.os.Parcelable; 229182d3c4eb1f9065cb33df5a3594969dd0d42accMike Lockwoodimport android.util.Log; 239182d3c4eb1f9065cb33df5a3594969dd0d42accMike Lockwood 249182d3c4eb1f9065cb33df5a3594969dd0d42accMike Lockwood/** 2511dd5ae97b1cd5889bb66862fd12718da62a9c75Mike Lockwood * A class representing a USB accessory, which is an external hardware component 2611dd5ae97b1cd5889bb66862fd12718da62a9c75Mike Lockwood * that communicates with an android application over USB. 2711dd5ae97b1cd5889bb66862fd12718da62a9c75Mike Lockwood * The accessory is the USB host and android the device side of the USB connection. 2811dd5ae97b1cd5889bb66862fd12718da62a9c75Mike Lockwood * 2911dd5ae97b1cd5889bb66862fd12718da62a9c75Mike Lockwood * <p>When the accessory connects, it reports its manufacturer and model names, 3011dd5ae97b1cd5889bb66862fd12718da62a9c75Mike Lockwood * the version of the accessory, and a user visible description of the accessory to the device. 3111dd5ae97b1cd5889bb66862fd12718da62a9c75Mike Lockwood * The manufacturer, model and version strings are used by the USB Manager to choose 3211dd5ae97b1cd5889bb66862fd12718da62a9c75Mike Lockwood * an appropriate application for the accessory. 3311dd5ae97b1cd5889bb66862fd12718da62a9c75Mike Lockwood * The accessory may optionally provide a unique serial number 3411dd5ae97b1cd5889bb66862fd12718da62a9c75Mike Lockwood * and a URL to for the accessory's website to the device as well. 3511dd5ae97b1cd5889bb66862fd12718da62a9c75Mike Lockwood * 3611dd5ae97b1cd5889bb66862fd12718da62a9c75Mike Lockwood * <p>An instance of this class is sent to the application via the 3711dd5ae97b1cd5889bb66862fd12718da62a9c75Mike Lockwood * {@link UsbManager#ACTION_USB_ACCESSORY_ATTACHED} Intent. 3811dd5ae97b1cd5889bb66862fd12718da62a9c75Mike Lockwood * The application can then call {@link UsbManager#openAccessory} to open a file descriptor 3911dd5ae97b1cd5889bb66862fd12718da62a9c75Mike Lockwood * for reading and writing data to and from the accessory. 403aef8e1d1b2f0b87d470bcccf37ba4ebb6560c45Joe Fernandez * 413aef8e1d1b2f0b87d470bcccf37ba4ebb6560c45Joe Fernandez * <div class="special reference"> 423aef8e1d1b2f0b87d470bcccf37ba4ebb6560c45Joe Fernandez * <h3>Developer Guides</h3> 433aef8e1d1b2f0b87d470bcccf37ba4ebb6560c45Joe Fernandez * <p>For more information about communicating with USB hardware, read the 443aef8e1d1b2f0b87d470bcccf37ba4ebb6560c45Joe Fernandez * <a href="{@docRoot}guide/topics/usb/index.html">USB</a> developer guide.</p> 453aef8e1d1b2f0b87d470bcccf37ba4ebb6560c45Joe Fernandez * </div> 469182d3c4eb1f9065cb33df5a3594969dd0d42accMike Lockwood */ 47c4308f01c965571dc2354107c3574df113e397eeMike Lockwoodpublic class UsbAccessory implements Parcelable { 489182d3c4eb1f9065cb33df5a3594969dd0d42accMike Lockwood 499182d3c4eb1f9065cb33df5a3594969dd0d42accMike Lockwood private static final String TAG = "UsbAccessory"; 509182d3c4eb1f9065cb33df5a3594969dd0d42accMike Lockwood 51c4308f01c965571dc2354107c3574df113e397eeMike Lockwood private final String mManufacturer; 52c4308f01c965571dc2354107c3574df113e397eeMike Lockwood private final String mModel; 53ac36d7c715a9cd793b2dce6de547594810101c3aMike Lockwood private final String mDescription; 54c4308f01c965571dc2354107c3574df113e397eeMike Lockwood private final String mVersion; 55ac36d7c715a9cd793b2dce6de547594810101c3aMike Lockwood private final String mUri; 56015b1ecaec27b7cf5f1a78099d9ae34a0c3169f2Mike Lockwood private final String mSerial; 579182d3c4eb1f9065cb33df5a3594969dd0d42accMike Lockwood 58166b05e0ce913711d27ce1a116b3f1fd906822e4Mike Lockwood /** @hide */ 59166b05e0ce913711d27ce1a116b3f1fd906822e4Mike Lockwood public static final int MANUFACTURER_STRING = 0; 60166b05e0ce913711d27ce1a116b3f1fd906822e4Mike Lockwood /** @hide */ 61166b05e0ce913711d27ce1a116b3f1fd906822e4Mike Lockwood public static final int MODEL_STRING = 1; 62166b05e0ce913711d27ce1a116b3f1fd906822e4Mike Lockwood /** @hide */ 63166b05e0ce913711d27ce1a116b3f1fd906822e4Mike Lockwood public static final int DESCRIPTION_STRING = 2; 64166b05e0ce913711d27ce1a116b3f1fd906822e4Mike Lockwood /** @hide */ 65166b05e0ce913711d27ce1a116b3f1fd906822e4Mike Lockwood public static final int VERSION_STRING = 3; 66166b05e0ce913711d27ce1a116b3f1fd906822e4Mike Lockwood /** @hide */ 67166b05e0ce913711d27ce1a116b3f1fd906822e4Mike Lockwood public static final int URI_STRING = 4; 68166b05e0ce913711d27ce1a116b3f1fd906822e4Mike Lockwood /** @hide */ 69166b05e0ce913711d27ce1a116b3f1fd906822e4Mike Lockwood public static final int SERIAL_STRING = 5; 70166b05e0ce913711d27ce1a116b3f1fd906822e4Mike Lockwood 719182d3c4eb1f9065cb33df5a3594969dd0d42accMike Lockwood /** 729182d3c4eb1f9065cb33df5a3594969dd0d42accMike Lockwood * UsbAccessory should only be instantiated by UsbService implementation 739182d3c4eb1f9065cb33df5a3594969dd0d42accMike Lockwood * @hide 749182d3c4eb1f9065cb33df5a3594969dd0d42accMike Lockwood */ 75ac36d7c715a9cd793b2dce6de547594810101c3aMike Lockwood public UsbAccessory(String manufacturer, String model, String description, 76015b1ecaec27b7cf5f1a78099d9ae34a0c3169f2Mike Lockwood String version, String uri, String serial) { 779182d3c4eb1f9065cb33df5a3594969dd0d42accMike Lockwood mManufacturer = manufacturer; 789182d3c4eb1f9065cb33df5a3594969dd0d42accMike Lockwood mModel = model; 79ac36d7c715a9cd793b2dce6de547594810101c3aMike Lockwood mDescription = description; 809182d3c4eb1f9065cb33df5a3594969dd0d42accMike Lockwood mVersion = version; 81ac36d7c715a9cd793b2dce6de547594810101c3aMike Lockwood mUri = uri; 82015b1ecaec27b7cf5f1a78099d9ae34a0c3169f2Mike Lockwood mSerial = serial; 839182d3c4eb1f9065cb33df5a3594969dd0d42accMike Lockwood } 849182d3c4eb1f9065cb33df5a3594969dd0d42accMike Lockwood 859182d3c4eb1f9065cb33df5a3594969dd0d42accMike Lockwood /** 869182d3c4eb1f9065cb33df5a3594969dd0d42accMike Lockwood * UsbAccessory should only be instantiated by UsbService implementation 879182d3c4eb1f9065cb33df5a3594969dd0d42accMike Lockwood * @hide 889182d3c4eb1f9065cb33df5a3594969dd0d42accMike Lockwood */ 899182d3c4eb1f9065cb33df5a3594969dd0d42accMike Lockwood public UsbAccessory(String[] strings) { 90166b05e0ce913711d27ce1a116b3f1fd906822e4Mike Lockwood mManufacturer = strings[MANUFACTURER_STRING]; 91166b05e0ce913711d27ce1a116b3f1fd906822e4Mike Lockwood mModel = strings[MODEL_STRING]; 92166b05e0ce913711d27ce1a116b3f1fd906822e4Mike Lockwood mDescription = strings[DESCRIPTION_STRING]; 93166b05e0ce913711d27ce1a116b3f1fd906822e4Mike Lockwood mVersion = strings[VERSION_STRING]; 94166b05e0ce913711d27ce1a116b3f1fd906822e4Mike Lockwood mUri = strings[URI_STRING]; 95166b05e0ce913711d27ce1a116b3f1fd906822e4Mike Lockwood mSerial = strings[SERIAL_STRING]; 969182d3c4eb1f9065cb33df5a3594969dd0d42accMike Lockwood } 979182d3c4eb1f9065cb33df5a3594969dd0d42accMike Lockwood 989182d3c4eb1f9065cb33df5a3594969dd0d42accMike Lockwood /** 9911dd5ae97b1cd5889bb66862fd12718da62a9c75Mike Lockwood * Returns the manufacturer name of the accessory. 1009182d3c4eb1f9065cb33df5a3594969dd0d42accMike Lockwood * 1019182d3c4eb1f9065cb33df5a3594969dd0d42accMike Lockwood * @return the accessory manufacturer 1029182d3c4eb1f9065cb33df5a3594969dd0d42accMike Lockwood */ 1039182d3c4eb1f9065cb33df5a3594969dd0d42accMike Lockwood public String getManufacturer() { 1049182d3c4eb1f9065cb33df5a3594969dd0d42accMike Lockwood return mManufacturer; 1059182d3c4eb1f9065cb33df5a3594969dd0d42accMike Lockwood } 1069182d3c4eb1f9065cb33df5a3594969dd0d42accMike Lockwood 1079182d3c4eb1f9065cb33df5a3594969dd0d42accMike Lockwood /** 1089182d3c4eb1f9065cb33df5a3594969dd0d42accMike Lockwood * Returns the model name of the accessory. 1099182d3c4eb1f9065cb33df5a3594969dd0d42accMike Lockwood * 1109182d3c4eb1f9065cb33df5a3594969dd0d42accMike Lockwood * @return the accessory model 1119182d3c4eb1f9065cb33df5a3594969dd0d42accMike Lockwood */ 1129182d3c4eb1f9065cb33df5a3594969dd0d42accMike Lockwood public String getModel() { 1139182d3c4eb1f9065cb33df5a3594969dd0d42accMike Lockwood return mModel; 1149182d3c4eb1f9065cb33df5a3594969dd0d42accMike Lockwood } 1159182d3c4eb1f9065cb33df5a3594969dd0d42accMike Lockwood 1169182d3c4eb1f9065cb33df5a3594969dd0d42accMike Lockwood /** 117ac36d7c715a9cd793b2dce6de547594810101c3aMike Lockwood * Returns a user visible description of the accessory. 1189182d3c4eb1f9065cb33df5a3594969dd0d42accMike Lockwood * 119ac36d7c715a9cd793b2dce6de547594810101c3aMike Lockwood * @return the accessory description 1209182d3c4eb1f9065cb33df5a3594969dd0d42accMike Lockwood */ 121ac36d7c715a9cd793b2dce6de547594810101c3aMike Lockwood public String getDescription() { 122ac36d7c715a9cd793b2dce6de547594810101c3aMike Lockwood return mDescription; 1239182d3c4eb1f9065cb33df5a3594969dd0d42accMike Lockwood } 1249182d3c4eb1f9065cb33df5a3594969dd0d42accMike Lockwood 1259182d3c4eb1f9065cb33df5a3594969dd0d42accMike Lockwood /** 1269182d3c4eb1f9065cb33df5a3594969dd0d42accMike Lockwood * Returns the version of the accessory. 1279182d3c4eb1f9065cb33df5a3594969dd0d42accMike Lockwood * 1289182d3c4eb1f9065cb33df5a3594969dd0d42accMike Lockwood * @return the accessory version 1299182d3c4eb1f9065cb33df5a3594969dd0d42accMike Lockwood */ 1309182d3c4eb1f9065cb33df5a3594969dd0d42accMike Lockwood public String getVersion() { 1319182d3c4eb1f9065cb33df5a3594969dd0d42accMike Lockwood return mVersion; 1329182d3c4eb1f9065cb33df5a3594969dd0d42accMike Lockwood } 1339182d3c4eb1f9065cb33df5a3594969dd0d42accMike Lockwood 134ac36d7c715a9cd793b2dce6de547594810101c3aMike Lockwood /** 135ac36d7c715a9cd793b2dce6de547594810101c3aMike Lockwood * Returns the URI for the accessory. 136ac36d7c715a9cd793b2dce6de547594810101c3aMike Lockwood * This is an optional URI that might show information about the accessory 137ac36d7c715a9cd793b2dce6de547594810101c3aMike Lockwood * or provide the option to download an application for the accessory 138ac36d7c715a9cd793b2dce6de547594810101c3aMike Lockwood * 139ac36d7c715a9cd793b2dce6de547594810101c3aMike Lockwood * @return the accessory URI 140ac36d7c715a9cd793b2dce6de547594810101c3aMike Lockwood */ 141ac36d7c715a9cd793b2dce6de547594810101c3aMike Lockwood public String getUri() { 142ac36d7c715a9cd793b2dce6de547594810101c3aMike Lockwood return mUri; 143ac36d7c715a9cd793b2dce6de547594810101c3aMike Lockwood } 144ac36d7c715a9cd793b2dce6de547594810101c3aMike Lockwood 145015b1ecaec27b7cf5f1a78099d9ae34a0c3169f2Mike Lockwood /** 146015b1ecaec27b7cf5f1a78099d9ae34a0c3169f2Mike Lockwood * Returns the unique serial number for the accessory. 147015b1ecaec27b7cf5f1a78099d9ae34a0c3169f2Mike Lockwood * This is an optional serial number that can be used to differentiate 148015b1ecaec27b7cf5f1a78099d9ae34a0c3169f2Mike Lockwood * between individual accessories of the same model and manufacturer 149015b1ecaec27b7cf5f1a78099d9ae34a0c3169f2Mike Lockwood * 150015b1ecaec27b7cf5f1a78099d9ae34a0c3169f2Mike Lockwood * @return the unique serial number 151015b1ecaec27b7cf5f1a78099d9ae34a0c3169f2Mike Lockwood */ 152015b1ecaec27b7cf5f1a78099d9ae34a0c3169f2Mike Lockwood public String getSerial() { 153015b1ecaec27b7cf5f1a78099d9ae34a0c3169f2Mike Lockwood return mSerial; 154015b1ecaec27b7cf5f1a78099d9ae34a0c3169f2Mike Lockwood } 155015b1ecaec27b7cf5f1a78099d9ae34a0c3169f2Mike Lockwood 15602eb8746de2d60563ec2751a34d20923192e4293Mike Lockwood private static boolean compare(String s1, String s2) { 15702eb8746de2d60563ec2751a34d20923192e4293Mike Lockwood if (s1 == null) return (s2 == null); 15802eb8746de2d60563ec2751a34d20923192e4293Mike Lockwood return s1.equals(s2); 15902eb8746de2d60563ec2751a34d20923192e4293Mike Lockwood } 16002eb8746de2d60563ec2751a34d20923192e4293Mike Lockwood 16102eb8746de2d60563ec2751a34d20923192e4293Mike Lockwood @Override 16202eb8746de2d60563ec2751a34d20923192e4293Mike Lockwood public boolean equals(Object obj) { 16302eb8746de2d60563ec2751a34d20923192e4293Mike Lockwood if (obj instanceof UsbAccessory) { 16402eb8746de2d60563ec2751a34d20923192e4293Mike Lockwood UsbAccessory accessory = (UsbAccessory)obj; 16502eb8746de2d60563ec2751a34d20923192e4293Mike Lockwood return (compare(mManufacturer, accessory.getManufacturer()) && 16602eb8746de2d60563ec2751a34d20923192e4293Mike Lockwood compare(mModel, accessory.getModel()) && 167ac36d7c715a9cd793b2dce6de547594810101c3aMike Lockwood compare(mDescription, accessory.getDescription()) && 168ac36d7c715a9cd793b2dce6de547594810101c3aMike Lockwood compare(mVersion, accessory.getVersion()) && 169015b1ecaec27b7cf5f1a78099d9ae34a0c3169f2Mike Lockwood compare(mUri, accessory.getUri()) && 170015b1ecaec27b7cf5f1a78099d9ae34a0c3169f2Mike Lockwood compare(mSerial, accessory.getSerial())); 17102eb8746de2d60563ec2751a34d20923192e4293Mike Lockwood } 17202eb8746de2d60563ec2751a34d20923192e4293Mike Lockwood return false; 17302eb8746de2d60563ec2751a34d20923192e4293Mike Lockwood } 17402eb8746de2d60563ec2751a34d20923192e4293Mike Lockwood 1759182d3c4eb1f9065cb33df5a3594969dd0d42accMike Lockwood @Override 176c6f23e8521dedac7a07119031913235be3ca37c3Mike Lockwood public int hashCode() { 177c6f23e8521dedac7a07119031913235be3ca37c3Mike Lockwood return ((mManufacturer == null ? 0 : mManufacturer.hashCode()) ^ 178c6f23e8521dedac7a07119031913235be3ca37c3Mike Lockwood (mModel == null ? 0 : mModel.hashCode()) ^ 179ac36d7c715a9cd793b2dce6de547594810101c3aMike Lockwood (mDescription == null ? 0 : mDescription.hashCode()) ^ 180ac36d7c715a9cd793b2dce6de547594810101c3aMike Lockwood (mVersion == null ? 0 : mVersion.hashCode()) ^ 181015b1ecaec27b7cf5f1a78099d9ae34a0c3169f2Mike Lockwood (mUri == null ? 0 : mUri.hashCode()) ^ 182015b1ecaec27b7cf5f1a78099d9ae34a0c3169f2Mike Lockwood (mSerial == null ? 0 : mSerial.hashCode())); 183c6f23e8521dedac7a07119031913235be3ca37c3Mike Lockwood } 184c6f23e8521dedac7a07119031913235be3ca37c3Mike Lockwood 185c6f23e8521dedac7a07119031913235be3ca37c3Mike Lockwood @Override 1869182d3c4eb1f9065cb33df5a3594969dd0d42accMike Lockwood public String toString() { 1879182d3c4eb1f9065cb33df5a3594969dd0d42accMike Lockwood return "UsbAccessory[mManufacturer=" + mManufacturer + 1889182d3c4eb1f9065cb33df5a3594969dd0d42accMike Lockwood ", mModel=" + mModel + 189ac36d7c715a9cd793b2dce6de547594810101c3aMike Lockwood ", mDescription=" + mDescription + 190ac36d7c715a9cd793b2dce6de547594810101c3aMike Lockwood ", mVersion=" + mVersion + 191015b1ecaec27b7cf5f1a78099d9ae34a0c3169f2Mike Lockwood ", mUri=" + mUri + 192015b1ecaec27b7cf5f1a78099d9ae34a0c3169f2Mike Lockwood ", mSerial=" + mSerial + "]"; 1939182d3c4eb1f9065cb33df5a3594969dd0d42accMike Lockwood } 1949182d3c4eb1f9065cb33df5a3594969dd0d42accMike Lockwood 1959182d3c4eb1f9065cb33df5a3594969dd0d42accMike Lockwood public static final Parcelable.Creator<UsbAccessory> CREATOR = 1969182d3c4eb1f9065cb33df5a3594969dd0d42accMike Lockwood new Parcelable.Creator<UsbAccessory>() { 1979182d3c4eb1f9065cb33df5a3594969dd0d42accMike Lockwood public UsbAccessory createFromParcel(Parcel in) { 1989182d3c4eb1f9065cb33df5a3594969dd0d42accMike Lockwood String manufacturer = in.readString(); 1999182d3c4eb1f9065cb33df5a3594969dd0d42accMike Lockwood String model = in.readString(); 200ac36d7c715a9cd793b2dce6de547594810101c3aMike Lockwood String description = in.readString(); 2019182d3c4eb1f9065cb33df5a3594969dd0d42accMike Lockwood String version = in.readString(); 202ac36d7c715a9cd793b2dce6de547594810101c3aMike Lockwood String uri = in.readString(); 203015b1ecaec27b7cf5f1a78099d9ae34a0c3169f2Mike Lockwood String serial = in.readString(); 204015b1ecaec27b7cf5f1a78099d9ae34a0c3169f2Mike Lockwood return new UsbAccessory(manufacturer, model, description, version, uri, serial); 2059182d3c4eb1f9065cb33df5a3594969dd0d42accMike Lockwood } 2069182d3c4eb1f9065cb33df5a3594969dd0d42accMike Lockwood 2079182d3c4eb1f9065cb33df5a3594969dd0d42accMike Lockwood public UsbAccessory[] newArray(int size) { 2089182d3c4eb1f9065cb33df5a3594969dd0d42accMike Lockwood return new UsbAccessory[size]; 2099182d3c4eb1f9065cb33df5a3594969dd0d42accMike Lockwood } 2109182d3c4eb1f9065cb33df5a3594969dd0d42accMike Lockwood }; 2119182d3c4eb1f9065cb33df5a3594969dd0d42accMike Lockwood 2129182d3c4eb1f9065cb33df5a3594969dd0d42accMike Lockwood public int describeContents() { 2139182d3c4eb1f9065cb33df5a3594969dd0d42accMike Lockwood return 0; 2149182d3c4eb1f9065cb33df5a3594969dd0d42accMike Lockwood } 2159182d3c4eb1f9065cb33df5a3594969dd0d42accMike Lockwood 2169182d3c4eb1f9065cb33df5a3594969dd0d42accMike Lockwood public void writeToParcel(Parcel parcel, int flags) { 2179182d3c4eb1f9065cb33df5a3594969dd0d42accMike Lockwood parcel.writeString(mManufacturer); 2189182d3c4eb1f9065cb33df5a3594969dd0d42accMike Lockwood parcel.writeString(mModel); 219ac36d7c715a9cd793b2dce6de547594810101c3aMike Lockwood parcel.writeString(mDescription); 2209182d3c4eb1f9065cb33df5a3594969dd0d42accMike Lockwood parcel.writeString(mVersion); 221ac36d7c715a9cd793b2dce6de547594810101c3aMike Lockwood parcel.writeString(mUri); 222015b1ecaec27b7cf5f1a78099d9ae34a0c3169f2Mike Lockwood parcel.writeString(mSerial); 2239182d3c4eb1f9065cb33df5a3594969dd0d42accMike Lockwood } 2249182d3c4eb1f9065cb33df5a3594969dd0d42accMike Lockwood} 225