1 /* 2 * Copyright (C) 2015 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 package com.android.car.vehiclenetwork; 17 18 import static com.android.car.vehiclenetwork.VehiclePropValueUtil.getVectorLength; 19 import static com.android.car.vehiclenetwork.VehiclePropValueUtil.isCustomProperty; 20 import static com.android.car.vehiclenetwork.VehiclePropValueUtil.toFloatArray; 21 import static com.android.car.vehiclenetwork.VehiclePropValueUtil.toIntArray; 22 23 import android.os.Handler; 24 import android.os.Looper; 25 import android.os.Message; 26 import android.os.RemoteException; 27 import android.os.ServiceManager; 28 import android.os.ServiceSpecificException; 29 import android.util.Log; 30 31 import com.android.car.vehiclenetwork.VehicleNetworkConsts.VehicleValueType; 32 import com.android.car.vehiclenetwork.VehicleNetworkProto.VehiclePropConfigs; 33 import com.android.car.vehiclenetwork.VehicleNetworkProto.VehiclePropValue; 34 import com.android.car.vehiclenetwork.VehicleNetworkProto.VehiclePropValues; 35 import com.android.internal.annotations.GuardedBy; 36 37 import java.lang.ref.WeakReference; 38 39 /** 40 * System API to access Vehicle network. This is only for system services and applications should 41 * not use this. All APIs will fail with security error if normal app tries this. 42 */ 43 public class VehicleNetwork { 44 /** 45 * Listener for VNS events. 46 */ 47 public interface VehicleNetworkListener { 48 /** 49 * Notify HAL events. This requires subscribing the property 50 */ 51 void onVehicleNetworkEvents(VehiclePropValues values); 52 void onHalError(int errorCode, int property, int operation); 53 void onHalRestart(boolean inMocking); 54 } 55 56 public interface VehicleNetworkHalMock { 57 VehiclePropConfigs onListProperties(); 58 void onPropertySet(VehiclePropValue value); 59 VehiclePropValue onPropertyGet(VehiclePropValue value); 60 void onPropertySubscribe(int property, float sampleRate, int zones); 61 void onPropertyUnsubscribe(int property); 62 } 63 64 private static final String TAG = VehicleNetwork.class.getSimpleName(); 65 66 private final IVehicleNetwork mService; 67 private final VehicleNetworkListener mListener; 68 private final IVehicleNetworkListenerImpl mVehicleNetworkListener; 69 private final EventHandler mEventHandler; 70 71 @GuardedBy("this") 72 private VehicleNetworkHalMock mHalMock; 73 private IVehicleNetworkHalMock mHalMockImpl; 74 75 private static final int VNS_CONNECT_MAX_RETRY = 10; 76 private static final long VNS_RETRY_WAIT_TIME_MS = 1000; 77 private static final int NO_ZONE = -1; 78 79 /** 80 * Factory method to create VehicleNetwork 81 * 82 * @param listener listener for listening events 83 * @param looper Looper to dispatch listener events 84 */ 85 public static VehicleNetwork createVehicleNetwork(VehicleNetworkListener listener, 86 Looper looper) { 87 int retryCount = 0; 88 IVehicleNetwork service = null; 89 while (service == null) { 90 service = IVehicleNetwork.Stub.asInterface(ServiceManager.getService( 91 IVehicleNetwork.class.getCanonicalName())); 92 retryCount++; 93 if (retryCount > VNS_CONNECT_MAX_RETRY) { 94 break; 95 } 96 try { 97 Thread.sleep(VNS_RETRY_WAIT_TIME_MS); 98 } catch (InterruptedException e) { 99 //ignore 100 } 101 } 102 if (service == null) { 103 throw new RuntimeException("Vehicle network service not available:" + 104 IVehicleNetwork.class.getCanonicalName()); 105 } 106 return new VehicleNetwork(service, listener, looper); 107 } 108 109 private VehicleNetwork(IVehicleNetwork service, VehicleNetworkListener listener, 110 Looper looper) { 111 mService = service; 112 mListener = listener; 113 mEventHandler = new EventHandler(looper); 114 mVehicleNetworkListener = new IVehicleNetworkListenerImpl(this); 115 } 116 117 /** 118 * List all properties from vehicle HAL 119 * 120 * @return all properties 121 */ 122 public VehiclePropConfigs listProperties() { 123 return listProperties(0 /* all */); 124 } 125 126 /** 127 * Return configuration information of single property 128 * 129 * @param property vehicle property number defined in {@link VehicleNetworkConsts}. 0 has has 130 * special meaning of list all properties. 131 * @return null if given property does not exist. 132 */ 133 public VehiclePropConfigs listProperties(int property) { 134 try { 135 VehiclePropConfigsParcelable parcelable = mService.listProperties(property); 136 if (parcelable != null) { 137 return parcelable.configs; 138 } 139 } catch (RemoteException e) { 140 handleRemoteException(e); 141 } 142 return null; 143 } 144 145 /** 146 * Set property which will lead into writing the value to vehicle HAL. 147 * 148 * @throws IllegalArgumentException If value set has wrong value like wrong valueType, wrong 149 * data, and etc. 150 */ 151 public void setProperty(VehiclePropValue value) throws IllegalArgumentException { 152 VehiclePropValueParcelable parcelable = new VehiclePropValueParcelable(value); 153 try { 154 mService.setProperty(parcelable); 155 } catch (RemoteException e) { 156 handleRemoteException(e); 157 } 158 } 159 160 /** 161 * Set integer type property 162 * 163 * @throws IllegalArgumentException For type mismatch (=the property is not int type) 164 */ 165 public void setIntProperty(int property, int value) throws IllegalArgumentException { 166 VehiclePropValue v = VehiclePropValueUtil.createIntValue(property, value, 0); 167 setProperty(v); 168 } 169 170 /** 171 * Set int vector type property. Length of passed values should match with vector length. 172 */ 173 public void setIntVectorProperty(int property, int[] values) throws IllegalArgumentException { 174 VehiclePropValue v = VehiclePropValueUtil.createIntVectorValue(property, values, 0); 175 setProperty(v); 176 } 177 178 /** 179 * Set long type property. 180 */ 181 public void setLongProperty(int property, long value) throws IllegalArgumentException { 182 VehiclePropValue v = VehiclePropValueUtil.createLongValue(property, value, 0); 183 setProperty(v); 184 } 185 186 /** 187 * Set float type property. 188 */ 189 public void setFloatProperty(int property, float value) throws IllegalArgumentException { 190 VehiclePropValue v = VehiclePropValueUtil.createFloatValue(property, value, 0); 191 setProperty(v); 192 } 193 194 /** 195 * Set float vector type property. Length of values should match with vector length. 196 */ 197 public void setFloatVectorProperty(int property, float[] values) 198 throws IllegalArgumentException { 199 VehiclePropValue v = VehiclePropValueUtil.createFloatVectorValue(property, values, 0); 200 setProperty(v); 201 } 202 203 /** 204 * Set zoned boolean type property 205 * 206 * @throws IllegalArgumentException For type mismatch (=the property is not boolean type) 207 */ 208 public void setBooleanProperty(int property, boolean value) 209 throws IllegalArgumentException { 210 VehiclePropValue v = VehiclePropValueUtil.createBooleanValue(property, value, 0); 211 setProperty(v); 212 } 213 214 /** 215 * Set zoned boolean type property 216 * 217 * @throws IllegalArgumentException For type mismatch (=the property is not boolean type) 218 */ 219 public void setZonedBooleanProperty(int property, int zone, boolean value) 220 throws IllegalArgumentException { 221 VehiclePropValue v = VehiclePropValueUtil.createZonedBooleanValue(property, zone, value, 0); 222 setProperty(v); 223 } 224 225 /** 226 * Set zoned float type property 227 * 228 * @throws IllegalArgumentException For type mismatch (=the property is not float type) 229 */ 230 public void setZonedFloatProperty(int property, int zone, float value) 231 throws IllegalArgumentException { 232 VehiclePropValue v = VehiclePropValueUtil.createZonedFloatValue(property, zone, value, 0); 233 setProperty(v); 234 } 235 236 /** 237 * Set zoned integer type property 238 * 239 * @throws IllegalArgumentException For type mismatch (=the property is not int type) 240 */ 241 public void setZonedIntProperty(int property, int zone, int value) 242 throws IllegalArgumentException { 243 VehiclePropValue v = VehiclePropValueUtil.createZonedIntValue(property, zone, value, 0); 244 setProperty(v); 245 } 246 247 /** 248 * Set zoned int vector type property. Length of passed values should match with vector length. 249 */ 250 public void setZonedIntVectorProperty(int property, int zone, int[] values) 251 throws IllegalArgumentException { 252 VehiclePropValue v = VehiclePropValueUtil 253 .createZonedIntVectorValue(property, zone, values, 0); 254 setProperty(v); 255 } 256 257 /** 258 * Set zoned float vector type property. Length of passed values should match with vector 259 * length. 260 */ 261 public void setZonedFloatVectorProperty(int property, int zone, float[] values) 262 throws IllegalArgumentException { 263 VehiclePropValue v = VehiclePropValueUtil 264 .createZonedFloatVectorValue(property, zone, values, 0); 265 setProperty(v); 266 } 267 268 /** 269 * Get property. This can be used for a property which does not require any other data. 270 */ 271 public VehiclePropValue getProperty(int property) throws IllegalArgumentException, 272 ServiceSpecificException { 273 int valueType = VehicleNetworkConsts.getVehicleValueType(property); 274 if (valueType == 0) { 275 throw new IllegalArgumentException("Data type is unknown for property: " + property); 276 } 277 VehiclePropValue value = VehiclePropValueUtil.createBuilder(property, valueType, 0).build(); 278 return getProperty(value); 279 } 280 281 /** 282 * Generic get method for any type of property. Some property may require setting data portion 283 * as get may return different result depending on the data set. 284 */ 285 public VehiclePropValue getProperty(VehiclePropValue value) throws IllegalArgumentException, 286 ServiceSpecificException { 287 VehiclePropValueParcelable parcelable = new VehiclePropValueParcelable(value); 288 try { 289 VehiclePropValueParcelable resParcelable = mService.getProperty(parcelable); 290 if (resParcelable != null) { 291 return resParcelable.value; 292 } 293 } catch (RemoteException e) { 294 handleRemoteException(e); 295 } 296 return null; 297 } 298 299 /** 300 * Get int type property. 301 */ 302 public int getIntProperty(int property) throws IllegalArgumentException, 303 ServiceSpecificException { 304 VehiclePropValue v = getProperty( 305 property, NO_ZONE, VehicleValueType.VEHICLE_VALUE_TYPE_INT32); 306 if (v.getInt32ValuesCount() != 1) { 307 throw new IllegalStateException(); 308 } 309 return v.getInt32Values(0); 310 } 311 312 /** 313 * Get zoned int type property. 314 */ 315 public int getZonedIntProperty(int property, int zone) throws IllegalArgumentException, 316 ServiceSpecificException { 317 VehiclePropValue v = getProperty( 318 property, zone, VehicleValueType.VEHICLE_VALUE_TYPE_ZONED_INT32); 319 if (v.getInt32ValuesCount() != 1) { 320 throw new IllegalStateException(); 321 } 322 return v.getInt32Values(0); 323 } 324 325 /** 326 * Get int vector type property. Length of values should match vector length. 327 */ 328 public int[] getIntVectorProperty(int property) throws IllegalArgumentException, 329 ServiceSpecificException { 330 VehiclePropValue v = getProperty( 331 property, NO_ZONE, VehicleValueType.VEHICLE_VALUE_TYPE_INT32); 332 assertVectorLength(v.getInt32ValuesCount(), property, v.getValueType()); 333 return toIntArray(v.getInt32ValuesList()); 334 } 335 336 /** 337 * Get zoned int vector type property. Length of values should match vector length. 338 */ 339 public int[] getZonedIntVectorProperty(int property, int zone) 340 throws IllegalArgumentException, ServiceSpecificException { 341 VehiclePropValue v = getProperty( 342 property, zone, VehicleValueType.VEHICLE_VALUE_TYPE_ZONED_INT32); 343 assertVectorLength(v.getInt32ValuesCount(), property, v.getValueType()); 344 return toIntArray(v.getInt32ValuesList()); 345 } 346 347 /** 348 * Get float type property. 349 */ 350 public float getFloatProperty(int property) throws IllegalArgumentException, 351 ServiceSpecificException { 352 VehiclePropValue v = getProperty( 353 property, NO_ZONE, VehicleValueType.VEHICLE_VALUE_TYPE_FLOAT); 354 if (v.getFloatValuesCount() != 1) { 355 throw new IllegalStateException(); 356 } 357 return v.getFloatValues(0); 358 } 359 360 /** 361 * Get float vector type property. Length of values should match vector's length. 362 */ 363 public float[] getFloatVectorProperty(int property) throws IllegalArgumentException, 364 ServiceSpecificException { 365 VehiclePropValue v = getProperty( 366 property, NO_ZONE, VehicleValueType.VEHICLE_VALUE_TYPE_FLOAT); 367 assertVectorLength(v.getFloatValuesCount(), property, v.getValueType()); 368 return toFloatArray(v.getFloatValuesList()); 369 } 370 371 /** 372 * Get zoned float vector type property. Length of values should match vector's length. 373 */ 374 public float[] getZonedFloatVectorProperty(int property, int zone) 375 throws IllegalArgumentException, ServiceSpecificException { 376 VehiclePropValue v = getProperty(property, zone, 377 VehicleValueType.VEHICLE_VALUE_TYPE_ZONED_FLOAT); 378 assertVectorLength(v.getFloatValuesCount(), property, v.getValueType()); 379 return toFloatArray(v.getFloatValuesList()); 380 } 381 382 /** 383 * Get long type property. 384 */ 385 public long getLongProperty(int property) throws IllegalArgumentException, 386 ServiceSpecificException { 387 VehiclePropValue v = getProperty( 388 property, NO_ZONE, VehicleValueType.VEHICLE_VALUE_TYPE_INT64); 389 return v.getInt64Value(); 390 } 391 392 /** 393 * Get string type property. 394 */ 395 //TODO check UTF8 to java string conversion 396 public String getStringProperty(int property) throws IllegalArgumentException, 397 ServiceSpecificException { 398 VehiclePropValue v = getProperty( 399 property, NO_ZONE, VehicleValueType.VEHICLE_VALUE_TYPE_STRING); 400 return v.getStringValue(); 401 } 402 403 /** 404 * Subscribe given property with given sample rate. 405 */ 406 public void subscribe(int property, float sampleRate) throws IllegalArgumentException { 407 subscribe(property, sampleRate, 0); 408 } 409 410 /** 411 * Subscribe given property with given sample rate. 412 */ 413 public void subscribe(int property, float sampleRate, int zones) 414 throws IllegalArgumentException { 415 try { 416 mService.subscribe(mVehicleNetworkListener, property, sampleRate, zones); 417 } catch (RemoteException e) { 418 handleRemoteException(e); 419 } 420 } 421 422 /** 423 * Stop subscribing the property. 424 */ 425 public void unsubscribe(int property) { 426 try { 427 mService.unsubscribe(mVehicleNetworkListener, property); 428 } catch (RemoteException e) { 429 handleRemoteException(e); 430 } 431 } 432 433 /** 434 * Inject given value to all clients subscribing the property. This is for testing. 435 */ 436 public synchronized void injectEvent(VehiclePropValue value) { 437 try { 438 mService.injectEvent(new VehiclePropValueParcelable(value)); 439 } catch (RemoteException e) { 440 handleRemoteException(e); 441 } 442 } 443 444 /** 445 * Start mocking of vehicle HAL. For testing only. 446 */ 447 public synchronized void startMocking(VehicleNetworkHalMock mock) { 448 mHalMock = mock; 449 mHalMockImpl = new IVehicleNetworkHalMockImpl(this); 450 try { 451 mService.startMocking(mHalMockImpl); 452 } catch (RemoteException e) { 453 handleRemoteException(e); 454 } 455 } 456 457 /** 458 * Stop mocking of vehicle HAL. For testing only. 459 */ 460 public synchronized void stopMocking() { 461 if (mHalMockImpl == null) { 462 return; 463 } 464 try { 465 mService.stopMocking(mHalMockImpl); 466 } catch (RemoteException e) { 467 handleRemoteException(e); 468 } finally { 469 mHalMock = null; 470 mHalMockImpl = null; 471 } 472 } 473 474 /** 475 * Start mocking of vehicle HAL. For testing only. 476 */ 477 public synchronized void startMocking(IVehicleNetworkHalMock mock) { 478 mHalMock = null; 479 mHalMockImpl = mock; 480 try { 481 mService.startMocking(mHalMockImpl); 482 } catch (RemoteException e) { 483 handleRemoteException(e); 484 } 485 } 486 487 /** 488 * Stop mocking of vehicle HAL. For testing only. 489 */ 490 public synchronized void stopMocking(IVehicleNetworkHalMock mock) { 491 if (mock.asBinder() != mHalMockImpl.asBinder()) { 492 return; 493 } 494 try { 495 mService.stopMocking(mHalMockImpl); 496 } catch (RemoteException e) { 497 handleRemoteException(e); 498 } finally { 499 mHalMock = null; 500 mHalMockImpl = null; 501 } 502 } 503 504 public synchronized void injectHalError(int errorCode, int property, int operation) { 505 try { 506 mService.injectHalError(errorCode, property, operation); 507 } catch (RemoteException e) { 508 handleRemoteException(e); 509 } 510 } 511 512 public synchronized void startErrorListening() { 513 try { 514 mService.startErrorListening(mVehicleNetworkListener); 515 } catch (RemoteException e) { 516 handleRemoteException(e); 517 } 518 } 519 520 public synchronized void stopErrorListening() { 521 try { 522 mService.stopErrorListening(mVehicleNetworkListener); 523 } catch (RemoteException e) { 524 handleRemoteException(e); 525 } 526 } 527 528 public synchronized void startHalRestartMonitoring() { 529 try { 530 mService.startHalRestartMonitoring(mVehicleNetworkListener); 531 } catch (RemoteException e) { 532 handleRemoteException(e); 533 } 534 } 535 536 public synchronized void stopHalRestartMonitoring() { 537 try { 538 mService.stopHalRestartMonitoring(mVehicleNetworkListener); 539 } catch (RemoteException e) { 540 handleRemoteException(e); 541 } 542 } 543 544 private synchronized VehicleNetworkHalMock getHalMock() { 545 return mHalMock; 546 } 547 548 private void handleRemoteException(RemoteException e) { 549 throw new RuntimeException("Vehicle network service not working ", e); 550 } 551 552 private void handleVehicleNetworkEvents(VehiclePropValues values) { 553 mListener.onVehicleNetworkEvents(values); 554 } 555 556 private void handleHalError(int errorCode, int property, int operation) { 557 mListener.onHalError(errorCode, property, operation); 558 } 559 560 private void handleHalRestart(boolean inMocking) { 561 mListener.onHalRestart(inMocking); 562 } 563 564 private class EventHandler extends Handler { 565 566 private static final int MSG_EVENTS = 0; 567 private static final int MSG_HAL_ERROR = 1; 568 private static final int MSG_HAL_RESTART = 2; 569 570 private EventHandler(Looper looper) { 571 super(looper); 572 } 573 574 private void notifyEvents(VehiclePropValues values) { 575 Message msg = obtainMessage(MSG_EVENTS, values); 576 sendMessage(msg); 577 } 578 579 private void notifyHalError(int errorCode, int property, int operation) { 580 Message msg = obtainMessage(MSG_HAL_ERROR, errorCode, property, operation); 581 sendMessage(msg); 582 } 583 584 private void notifyHalRestart(boolean inMocking) { 585 Message msg = obtainMessage(MSG_HAL_RESTART, inMocking ? 1 : 0, 0); 586 sendMessage(msg); 587 } 588 589 @Override 590 public void handleMessage(Message msg) { 591 switch (msg.what) { 592 case MSG_EVENTS: 593 handleVehicleNetworkEvents((VehiclePropValues) msg.obj); 594 break; 595 case MSG_HAL_ERROR: 596 handleHalError(msg.arg1, msg.arg2, (Integer) msg.obj); 597 break; 598 case MSG_HAL_RESTART: 599 handleHalRestart(msg.arg1 == 1); 600 break; 601 default: 602 Log.w(TAG, "Unknown message:" + msg.what, new RuntimeException()); 603 break; 604 } 605 } 606 } 607 608 private static class IVehicleNetworkListenerImpl extends IVehicleNetworkListener.Stub { 609 610 private final WeakReference<VehicleNetwork> mVehicleNetwork; 611 612 private IVehicleNetworkListenerImpl(VehicleNetwork vehicleNewotk) { 613 mVehicleNetwork = new WeakReference<>(vehicleNewotk); 614 } 615 616 @Override 617 public void onVehicleNetworkEvents(VehiclePropValuesParcelable values) { 618 VehicleNetwork vehicleNetwork = mVehicleNetwork.get(); 619 if (vehicleNetwork != null) { 620 vehicleNetwork.mEventHandler.notifyEvents(values.values); 621 } 622 } 623 624 @Override 625 public void onHalError(int errorCode, int property, int operation) { 626 VehicleNetwork vehicleNetwork = mVehicleNetwork.get(); 627 if (vehicleNetwork != null) { 628 vehicleNetwork.mEventHandler.notifyHalError(errorCode, property, operation); 629 } 630 } 631 632 @Override 633 public void onHalRestart(boolean inMocking) { 634 VehicleNetwork vehicleNetwork = mVehicleNetwork.get(); 635 if (vehicleNetwork != null) { 636 vehicleNetwork.mEventHandler.notifyHalRestart(inMocking); 637 } 638 } 639 } 640 641 private static class IVehicleNetworkHalMockImpl extends IVehicleNetworkHalMock.Stub { 642 private final WeakReference<VehicleNetwork> mVehicleNetwork; 643 644 private IVehicleNetworkHalMockImpl(VehicleNetwork vehicleNewotk) { 645 mVehicleNetwork = new WeakReference<>(vehicleNewotk); 646 } 647 648 @Override 649 public VehiclePropConfigsParcelable onListProperties() { 650 VehicleNetwork vehicleNetwork = mVehicleNetwork.get(); 651 if (vehicleNetwork == null) { 652 return null; 653 } 654 VehiclePropConfigs configs = vehicleNetwork.getHalMock().onListProperties(); 655 return new VehiclePropConfigsParcelable(configs); 656 } 657 658 @Override 659 public void onPropertySet(VehiclePropValueParcelable value) { 660 VehicleNetwork vehicleNetwork = mVehicleNetwork.get(); 661 if (vehicleNetwork == null) { 662 return; 663 } 664 vehicleNetwork.getHalMock().onPropertySet(value.value); 665 } 666 667 @Override 668 public VehiclePropValueParcelable onPropertyGet(VehiclePropValueParcelable value) { 669 VehicleNetwork vehicleNetwork = mVehicleNetwork.get(); 670 if (vehicleNetwork == null) { 671 return null; 672 } 673 VehiclePropValue resValue = vehicleNetwork.getHalMock().onPropertyGet(value.value); 674 return new VehiclePropValueParcelable(resValue); 675 } 676 677 @Override 678 public void onPropertySubscribe(int property, float sampleRate, int zones) { 679 VehicleNetwork vehicleNetwork = mVehicleNetwork.get(); 680 if (vehicleNetwork == null) { 681 return; 682 } 683 vehicleNetwork.getHalMock().onPropertySubscribe(property, sampleRate, zones); 684 } 685 686 @Override 687 public void onPropertyUnsubscribe(int property) { 688 VehicleNetwork vehicleNetwork = mVehicleNetwork.get(); 689 if (vehicleNetwork == null) { 690 return; 691 } 692 vehicleNetwork.getHalMock().onPropertyUnsubscribe(property); 693 } 694 } 695 696 private VehiclePropValue getProperty(int property, int zone, int customPropetyDataType) { 697 boolean isCustom = isCustomProperty(property); 698 int valueType = isCustom 699 ? customPropetyDataType 700 : VehicleNetworkConsts.getVehicleValueType(property); 701 702 VehiclePropValue.Builder valuePrototypeBuilder = 703 VehiclePropValueUtil.createBuilder(property, valueType, 0); 704 705 if (zone != NO_ZONE) { 706 valuePrototypeBuilder.setZone(zone); 707 } 708 709 VehiclePropValue v = getProperty(valuePrototypeBuilder.build()); 710 if (v == null) { 711 // if property is invalid, IllegalArgumentException should have been thrown 712 // from getProperty. 713 throw new IllegalStateException(); 714 } 715 716 if (!isCustom && v.getValueType() != valueType) { 717 throw new IllegalArgumentException( 718 "Unexpected type for property 0x" + Integer.toHexString(property) + 719 " got:0x" + Integer.toHexString(v.getValueType()) 720 + ", expecting:0x" + Integer.toHexString(valueType)); 721 } 722 return v; 723 } 724 725 private void assertVectorLength(int actual, int property, int valueType) { 726 int expectedLen = getVectorLength(valueType); 727 if (expectedLen != actual) { 728 throw new IllegalStateException("Invalid array size for property: " + property 729 + ". Expected: " + expectedLen 730 + ", actual: " + actual); 731 } 732 } 733 } 734