1 /* 2 * Copyright (C) 2024 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.internal.widget.remotecompose.core; 17 18 import android.annotation.NonNull; 19 import android.annotation.Nullable; 20 21 import com.android.internal.widget.remotecompose.core.operations.FloatExpression; 22 import com.android.internal.widget.remotecompose.core.operations.ShaderData; 23 import com.android.internal.widget.remotecompose.core.operations.Theme; 24 import com.android.internal.widget.remotecompose.core.operations.Utils; 25 import com.android.internal.widget.remotecompose.core.operations.layout.Component; 26 import com.android.internal.widget.remotecompose.core.operations.utilities.ArrayAccess; 27 import com.android.internal.widget.remotecompose.core.operations.utilities.CollectionsAccess; 28 import com.android.internal.widget.remotecompose.core.operations.utilities.DataMap; 29 import com.android.internal.widget.remotecompose.core.operations.utilities.IntMap; 30 31 import java.time.LocalDateTime; 32 import java.time.OffsetDateTime; 33 import java.time.ZoneId; 34 import java.time.ZoneOffset; 35 36 /** 37 * Specify an abstract context used to playback RemoteCompose documents 38 * 39 * <p>This allows us to intercept the different operations in a document and react to them. 40 * 41 * <p>We also contain a PaintContext, so that any operation can draw as needed. 42 */ 43 public abstract class RemoteContext { 44 private static final int MAX_OP_COUNT = 20_000; // Maximum cmds per frame 45 protected @NonNull CoreDocument mDocument = 46 new CoreDocument(); // todo: is this a valid way to initialize? bbade@ 47 public @NonNull RemoteComposeState mRemoteComposeState = 48 new RemoteComposeState(); // todo, is this a valid use of RemoteComposeState -- bbade@ 49 private long mDocLoadTime = System.currentTimeMillis(); 50 @Nullable protected PaintContext mPaintContext = null; 51 protected float mDensity = Float.NaN; 52 53 @NonNull ContextMode mMode = ContextMode.UNSET; 54 55 int mDebug = 0; 56 57 private int mOpCount; 58 private int mTheme = Theme.UNSPECIFIED; 59 60 public float mWidth = 0f; 61 public float mHeight = 0f; 62 private float mAnimationTime; 63 64 private boolean mAnimate = true; 65 66 public @Nullable Component mLastComponent; 67 public long currentTime = 0L; 68 69 private boolean mUseChoreographer = true; 70 71 /** 72 * Returns true if the document has been encoded for at least the given version MAJOR.MINOR 73 * 74 * @param major major version number 75 * @param minor minor version number 76 * @param patch patch version number 77 * @return true if the document was written at least with the given version 78 */ supportsVersion(int major, int minor, int patch)79 public boolean supportsVersion(int major, int minor, int patch) { 80 return mDocument.mVersion.supportsVersion(major, minor, patch); 81 } 82 getDensity()83 public float getDensity() { 84 return mDensity; 85 } 86 87 /** 88 * Set the density of the document 89 * 90 * @param density 91 */ setDensity(float density)92 public void setDensity(float density) { 93 if (!Float.isNaN(density) && density > 0) { 94 mDensity = density; 95 } 96 } 97 98 /** 99 * Get the time the document was loaded 100 * 101 * @return time in ms since the document was loaded 102 */ getDocLoadTime()103 public long getDocLoadTime() { 104 return mDocLoadTime; 105 } 106 107 /** Set the time the document was loaded */ setDocLoadTime()108 public void setDocLoadTime() { 109 mDocLoadTime = System.currentTimeMillis(); 110 } 111 isAnimationEnabled()112 public boolean isAnimationEnabled() { 113 return mAnimate; 114 } 115 setAnimationEnabled(boolean value)116 public void setAnimationEnabled(boolean value) { 117 mAnimate = value; 118 } 119 120 /** 121 * Provide access to the table of collections 122 * 123 * @return the CollectionsAccess implementation 124 */ getCollectionsAccess()125 public @Nullable CollectionsAccess getCollectionsAccess() { 126 return mRemoteComposeState; 127 } 128 129 /** 130 * Load a path under an id. Paths can be use in clip drawPath and drawTweenPath 131 * 132 * @param instanceId the id to save this path under 133 * @param floatPath the path as a float array 134 */ loadPathData(int instanceId, @NonNull float[] floatPath)135 public abstract void loadPathData(int instanceId, @NonNull float[] floatPath); 136 137 /** 138 * Load a path under an id. Paths can be use in clip drawPath and drawTweenPath 139 * 140 * @param instanceId 141 * @return the a 142 */ getPathData(int instanceId)143 public abstract @Nullable float[] getPathData(int instanceId); 144 145 /** 146 * Associate a name with a give id. 147 * 148 * @param varName the name 149 * @param varId the id (color,integer,float etc.) 150 * @param varType thetype 151 */ loadVariableName(@onNull String varName, int varId, int varType)152 public abstract void loadVariableName(@NonNull String varName, int varId, int varType); 153 154 /** 155 * Save a color under a given id 156 * 157 * @param id the id of the color 158 * @param color the color to set 159 */ loadColor(int id, int color)160 public abstract void loadColor(int id, int color); 161 162 /** 163 * Set the animation time allowing the creator to control animation rates 164 * 165 * @param time the animation time in seconds 166 */ setAnimationTime(float time)167 public void setAnimationTime(float time) { 168 mAnimationTime = time; 169 } 170 171 /** 172 * gets the time animation clock as float in seconds 173 * 174 * @return a monotonic time in seconds (arbitrary zero point) 175 */ getAnimationTime()176 public float getAnimationTime() { 177 return mAnimationTime; 178 } 179 180 /** 181 * Set the value of a named Color. This overrides the color in the document 182 * 183 * @param colorName the name of the color to override 184 * @param color Override the default color 185 */ setNamedColorOverride(@onNull String colorName, int color)186 public abstract void setNamedColorOverride(@NonNull String colorName, int color); 187 188 /** 189 * Set the value of a named String. This overrides the string in the document 190 * 191 * @param stringName the name of the string to override 192 * @param value Override the default string 193 */ setNamedStringOverride(@onNull String stringName, @NonNull String value)194 public abstract void setNamedStringOverride(@NonNull String stringName, @NonNull String value); 195 196 /** 197 * Allows to clear a named String. 198 * 199 * <p>If an override exists, we revert back to the default value in the document. 200 * 201 * @param stringName the name of the string to override 202 */ clearNamedStringOverride(@onNull String stringName)203 public abstract void clearNamedStringOverride(@NonNull String stringName); 204 205 /** 206 * Set the value of a named Integer. This overrides the integer in the document 207 * 208 * @param integerName the name of the integer to override 209 * @param value Override the default integer 210 */ setNamedIntegerOverride(@onNull String integerName, int value)211 public abstract void setNamedIntegerOverride(@NonNull String integerName, int value); 212 213 /** 214 * Allows to clear a named Integer. 215 * 216 * <p>If an override exists, we revert back to the default value in the document. 217 * 218 * @param integerName the name of the integer to override 219 */ clearNamedIntegerOverride(@onNull String integerName)220 public abstract void clearNamedIntegerOverride(@NonNull String integerName); 221 222 /** 223 * Set the value of a named float. This overrides the float in the document 224 * 225 * @param floatName the name of the float to override 226 * @param value Override the default float 227 */ setNamedFloatOverride(String floatName, float value)228 public abstract void setNamedFloatOverride(String floatName, float value); 229 230 /** 231 * Allows to clear a named Float. 232 * 233 * <p>If an override exists, we revert back to the default value in the document. 234 * 235 * @param floatName the name of the float to override 236 */ clearNamedFloatOverride(String floatName)237 public abstract void clearNamedFloatOverride(String floatName); 238 239 /** 240 * Set the value of a named long. This modifies the content of a LongConstant 241 * 242 * @param name the name of the float to override 243 * @param value Override the default float 244 */ setNamedLong(String name, long value)245 public abstract void setNamedLong(String name, long value); 246 247 /** 248 * Set the value of a named Object. This overrides the Object in the document 249 * 250 * @param dataName the name of the Object to override 251 * @param value Override the default float 252 */ setNamedDataOverride(String dataName, Object value)253 public abstract void setNamedDataOverride(String dataName, Object value); 254 255 /** 256 * Allows to clear a named Object. 257 * 258 * <p>If an override exists, we revert back to the default value in the document. 259 * 260 * @param dataName the name of the Object to override 261 */ clearNamedDataOverride(String dataName)262 public abstract void clearNamedDataOverride(String dataName); 263 264 /** 265 * Support Collections by registering this collection 266 * 267 * @param id id of the collection 268 * @param collection the collection under this id 269 */ addCollection(int id, @NonNull ArrayAccess collection)270 public abstract void addCollection(int id, @NonNull ArrayAccess collection); 271 272 /** 273 * put DataMap under an id 274 * 275 * @param id the id of the DataMap 276 * @param map the DataMap 277 */ putDataMap(int id, @NonNull DataMap map)278 public abstract void putDataMap(int id, @NonNull DataMap map); 279 280 /** 281 * Get a DataMap given an id 282 * 283 * @param id the id of the DataMap 284 * @return the DataMap 285 */ getDataMap(int id)286 public abstract @Nullable DataMap getDataMap(int id); 287 288 /** 289 * Run an action 290 * 291 * @param id the id of the action 292 * @param metadata the metadata of the action 293 */ runAction(int id, @NonNull String metadata)294 public abstract void runAction(int id, @NonNull String metadata); 295 296 // TODO: we might add an interface to group all valid parameter types 297 298 /** 299 * Run an action with a named parameter 300 * 301 * @param textId the text id of the action 302 * @param value the value of the parameter 303 */ runNamedAction(int textId, Object value)304 public abstract void runNamedAction(int textId, Object value); 305 306 /** 307 * Put an object under an id 308 * 309 * @param mId the id of the object 310 * @param command the object 311 */ putObject(int mId, @NonNull Object command)312 public abstract void putObject(int mId, @NonNull Object command); 313 314 /** 315 * Get an object given an id 316 * 317 * @param mId the id of the object 318 * @return the object 319 */ getObject(int mId)320 public abstract @Nullable Object getObject(int mId); 321 322 /** 323 * Add a touch listener to the context 324 * 325 * @param touchExpression the touch expression 326 */ addTouchListener(TouchListener touchExpression)327 public void addTouchListener(TouchListener touchExpression) {} 328 329 /** 330 * Vibrate the device 331 * 332 * @param type 0 = none, 1-21 ,see HapticFeedbackConstants 333 */ hapticEffect(int type)334 public abstract void hapticEffect(int type); 335 336 /** Set the repaint flag. This will trigger a repaint of the current document. */ needsRepaint()337 public void needsRepaint() { 338 if (mPaintContext != null) { 339 mPaintContext.needsRepaint(); 340 } 341 } 342 343 /** 344 * Returns true if we should use the choreographter 345 * 346 * @return true if we use the choreographer 347 */ useChoreographer()348 public boolean useChoreographer() { 349 return mUseChoreographer; 350 } 351 352 /** 353 * Set to true to use the android choreographer 354 * 355 * @param value 356 */ setUseChoreographer(boolean value)357 public void setUseChoreographer(boolean value) { 358 mUseChoreographer = value; 359 } 360 361 /** 362 * The context can be used in a few different mode, allowing operations to skip being executed: 363 * - UNSET : all operations will get executed - DATA : only operations dealing with DATA (eg 364 * loading a bitmap) should execute - PAINT : only operations painting should execute 365 */ 366 public enum ContextMode { 367 UNSET, 368 DATA, 369 PAINT 370 } 371 getTheme()372 public int getTheme() { 373 return mTheme; 374 } 375 setTheme(int theme)376 public void setTheme(int theme) { 377 this.mTheme = theme; 378 } 379 getMode()380 public @NonNull ContextMode getMode() { 381 return mMode; 382 } 383 setMode(@onNull ContextMode mode)384 public void setMode(@NonNull ContextMode mode) { 385 this.mMode = mode; 386 } 387 388 @Nullable getPaintContext()389 public PaintContext getPaintContext() { 390 return mPaintContext; 391 } 392 setPaintContext(@onNull PaintContext paintContext)393 public void setPaintContext(@NonNull PaintContext paintContext) { 394 this.mPaintContext = paintContext; 395 } 396 getDocument()397 public @Nullable CoreDocument getDocument() { 398 return mDocument; 399 } 400 isDebug()401 public boolean isDebug() { 402 return mDebug == 1; 403 } 404 isVisualDebug()405 public boolean isVisualDebug() { 406 return mDebug == 2; 407 } 408 setDebug(int debug)409 public void setDebug(int debug) { 410 this.mDebug = debug; 411 } 412 setDocument(@onNull CoreDocument document)413 public void setDocument(@NonNull CoreDocument document) { 414 this.mDocument = document; 415 } 416 417 /////////////////////////////////////////////////////////////////////////////////////////////// 418 // Operations 419 /////////////////////////////////////////////////////////////////////////////////////////////// 420 421 /** 422 * Set the main information about a document 423 * 424 * @param majorVersion major version of the document protocol used 425 * @param minorVersion minor version of the document protocol used 426 * @param patchVersion patch version of the document protocol used 427 * @param width original width of the document when created 428 * @param height original height of the document when created 429 * @param capabilities bitmask of capabilities used in the document (TBD) 430 * @param properties properties of the document (TBD) 431 */ header( int majorVersion, int minorVersion, int patchVersion, int width, int height, long capabilities, IntMap<Object> properties)432 public void header( 433 int majorVersion, 434 int minorVersion, 435 int patchVersion, 436 int width, 437 int height, 438 long capabilities, 439 IntMap<Object> properties) { 440 mRemoteComposeState.setWindowWidth(width); 441 mRemoteComposeState.setWindowHeight(height); 442 mDocument.setVersion(majorVersion, minorVersion, patchVersion); 443 mDocument.setWidth(width); 444 mDocument.setHeight(height); 445 mDocument.setRequiredCapabilities(capabilities); 446 mDocument.setProperties(properties); 447 } 448 449 /** 450 * Sets the way the player handles the content 451 * 452 * @param scroll set the horizontal behavior (NONE|SCROLL_HORIZONTAL|SCROLL_VERTICAL) 453 * @param alignment set the alignment of the content (TOP|CENTER|BOTTOM|START|END) 454 * @param sizing set the type of sizing for the content (NONE|SIZING_LAYOUT|SIZING_SCALE) 455 * @param mode set the mode of sizing, either LAYOUT modes or SCALE modes the LAYOUT modes are: 456 * - LAYOUT_MATCH_PARENT - LAYOUT_WRAP_CONTENT or adding an horizontal mode and a vertical 457 * mode: - LAYOUT_HORIZONTAL_MATCH_PARENT - LAYOUT_HORIZONTAL_WRAP_CONTENT - 458 * LAYOUT_HORIZONTAL_FIXED - LAYOUT_VERTICAL_MATCH_PARENT - LAYOUT_VERTICAL_WRAP_CONTENT - 459 * LAYOUT_VERTICAL_FIXED The LAYOUT_*_FIXED modes will use the intrinsic document size 460 */ setRootContentBehavior(int scroll, int alignment, int sizing, int mode)461 public void setRootContentBehavior(int scroll, int alignment, int sizing, int mode) { 462 mDocument.setRootContentBehavior(scroll, alignment, sizing, mode); 463 } 464 465 /** 466 * Set a content description for the document 467 * 468 * @param contentDescriptionId the text id pointing at the description 469 */ setDocumentContentDescription(int contentDescriptionId)470 public void setDocumentContentDescription(int contentDescriptionId) { 471 String contentDescription = (String) mRemoteComposeState.getFromId(contentDescriptionId); 472 mDocument.setContentDescription(contentDescription); 473 } 474 475 /////////////////////////////////////////////////////////////////////////////////////////////// 476 // Data handling 477 /////////////////////////////////////////////////////////////////////////////////////////////// 478 479 /** 480 * Save a bitmap under an imageId 481 * 482 * @param imageId the id of the image 483 * @param encoding how the data is encoded 0 = png, 1 = raw, 2 = url 484 * @param type the type of the data 0 = RGBA 8888, 1 = 888, 2 = 8 gray 485 * @param width the width of the image 486 * @param height the height of the image 487 * @param bitmap the bytes that represent the image 488 */ loadBitmap( int imageId, short encoding, short type, int width, int height, @NonNull byte[] bitmap)489 public abstract void loadBitmap( 490 int imageId, short encoding, short type, int width, int height, @NonNull byte[] bitmap); 491 492 /** 493 * Save a string under a given id 494 * 495 * @param id the id of the string 496 * @param text the value to set 497 */ loadText(int id, @NonNull String text)498 public abstract void loadText(int id, @NonNull String text); 499 500 /** 501 * Get a string given an id 502 * 503 * @param id the id of the string 504 * @return 505 */ getText(int id)506 public abstract @Nullable String getText(int id); 507 508 /** 509 * Load a float 510 * 511 * @param id id of the float 512 * @param value the value to set 513 */ loadFloat(int id, float value)514 public abstract void loadFloat(int id, float value); 515 516 /** 517 * Override an existing float value 518 * 519 * @param id 520 * @param value 521 */ overrideFloat(int id, float value)522 public abstract void overrideFloat(int id, float value); 523 524 /** 525 * Load a integer 526 * 527 * @param id id of the integer 528 * @param value the value to set 529 */ loadInteger(int id, int value)530 public abstract void loadInteger(int id, int value); 531 532 /** 533 * Override an existing int value 534 * 535 * @param id 536 * @param value 537 */ overrideInteger(int id, int value)538 public abstract void overrideInteger(int id, int value); 539 540 /** 541 * Override an existing text value 542 * 543 * @param id 544 * @param valueId 545 */ overrideText(int id, int valueId)546 public abstract void overrideText(int id, int valueId); 547 548 /** 549 * Load an animated float associated with an id Todo: Remove? cc @hoford 550 * 551 * @param id the id of the float 552 * @param animatedFloat The animated float 553 */ loadAnimatedFloat(int id, @NonNull FloatExpression animatedFloat)554 public abstract void loadAnimatedFloat(int id, @NonNull FloatExpression animatedFloat); 555 556 /** 557 * Save a shader under and ID 558 * 559 * @param id the id of the Shader 560 * @param value the shader 561 */ loadShader(int id, @NonNull ShaderData value)562 public abstract void loadShader(int id, @NonNull ShaderData value); 563 564 /** 565 * Get a float given an id 566 * 567 * @param id the id of the float 568 * @return the value of the float 569 */ getFloat(int id)570 public abstract float getFloat(int id); 571 572 /** 573 * Get a Integer given an id 574 * 575 * @param id of the integer 576 * @return the value 577 */ getInteger(int id)578 public abstract int getInteger(int id); 579 580 /** 581 * Get a Long given an id 582 * 583 * @param id of the long 584 * @return the value 585 */ getLong(int id)586 public abstract long getLong(int id); 587 588 /** 589 * Get the color given and ID 590 * 591 * @param id of the color 592 * @return the color 593 */ getColor(int id)594 public abstract int getColor(int id); 595 596 /** 597 * called to notify system that a command is interested in a variable 598 * 599 * @param id track when this id changes value 600 * @param variableSupport call back when value changes 601 */ listensTo(int id, @NonNull VariableSupport variableSupport)602 public abstract void listensTo(int id, @NonNull VariableSupport variableSupport); 603 604 /** 605 * Notify commands with variables have changed 606 * 607 * @return the number of ms to next update 608 */ updateOps()609 public abstract int updateOps(); 610 611 /** 612 * Get a shader given the id 613 * 614 * @param id get a shader given the id 615 * @return The shader 616 */ 617 @Nullable getShader(int id)618 public abstract ShaderData getShader(int id); 619 620 public static final int ID_CONTINUOUS_SEC = 1; 621 public static final int ID_TIME_IN_SEC = 2; 622 public static final int ID_TIME_IN_MIN = 3; 623 public static final int ID_TIME_IN_HR = 4; 624 public static final int ID_WINDOW_WIDTH = 5; 625 public static final int ID_WINDOW_HEIGHT = 6; 626 public static final int ID_COMPONENT_WIDTH = 7; 627 public static final int ID_COMPONENT_HEIGHT = 8; 628 public static final int ID_CALENDAR_MONTH = 9; 629 public static final int ID_OFFSET_TO_UTC = 10; 630 public static final int ID_WEEK_DAY = 11; 631 public static final int ID_DAY_OF_MONTH = 12; 632 public static final int ID_TOUCH_POS_X = 13; 633 public static final int ID_TOUCH_POS_Y = 14; 634 635 public static final int ID_TOUCH_VEL_X = 15; 636 public static final int ID_TOUCH_VEL_Y = 16; 637 638 public static final int ID_ACCELERATION_X = 17; 639 public static final int ID_ACCELERATION_Y = 18; 640 public static final int ID_ACCELERATION_Z = 19; 641 642 public static final int ID_GYRO_ROT_X = 20; 643 public static final int ID_GYRO_ROT_Y = 21; 644 public static final int ID_GYRO_ROT_Z = 22; 645 646 public static final int ID_MAGNETIC_X = 23; 647 public static final int ID_MAGNETIC_Y = 24; 648 public static final int ID_MAGNETIC_Z = 25; 649 650 public static final int ID_LIGHT = 26; 651 652 public static final int ID_DENSITY = 27; 653 654 /** Defines when the last build was made */ 655 public static final int ID_API_LEVEL = 28; 656 657 /** Defines when the TOUCH EVENT HAPPENED */ 658 public static final int ID_TOUCH_EVENT_TIME = 29; 659 660 /** Animation time in seconds */ 661 public static final int ID_ANIMATION_TIME = 30; 662 663 /** The delta between current and last Frame */ 664 public static final int ID_ANIMATION_DELTA_TIME = 31; 665 666 public static final int ID_EPOCH_SECOND = 32; 667 668 public static final int ID_FONT_SIZE = 33; 669 670 public static final float FLOAT_DENSITY = Utils.asNan(ID_DENSITY); 671 672 /** CONTINUOUS_SEC is seconds from midnight looping every hour 0-3600 */ 673 public static final float FLOAT_CONTINUOUS_SEC = Utils.asNan(ID_CONTINUOUS_SEC); 674 675 /** seconds run from Midnight=0 quantized to seconds hour 0..3599 */ 676 public static final float FLOAT_TIME_IN_SEC = Utils.asNan(ID_TIME_IN_SEC); 677 678 /** minutes run from Midnight=0 quantized to minutes 0..1439 */ 679 public static final float FLOAT_TIME_IN_MIN = Utils.asNan(ID_TIME_IN_MIN); 680 681 /** hours run from Midnight=0 quantized to Hours 0-23 */ 682 public static final float FLOAT_TIME_IN_HR = Utils.asNan(ID_TIME_IN_HR); 683 684 /** Moth of Year quantized to MONTHS 1-12. 1 = January */ 685 public static final float FLOAT_CALENDAR_MONTH = Utils.asNan(ID_CALENDAR_MONTH); 686 687 /** DAY OF THE WEEK 1-7. 1 = Monday */ 688 public static final float FLOAT_WEEK_DAY = Utils.asNan(ID_WEEK_DAY); 689 690 /** DAY OF THE MONTH 1-31 */ 691 public static final float FLOAT_DAY_OF_MONTH = Utils.asNan(ID_DAY_OF_MONTH); 692 693 public static final float FLOAT_WINDOW_WIDTH = Utils.asNan(ID_WINDOW_WIDTH); 694 public static final float FLOAT_WINDOW_HEIGHT = Utils.asNan(ID_WINDOW_HEIGHT); 695 public static final float FLOAT_COMPONENT_WIDTH = Utils.asNan(ID_COMPONENT_WIDTH); 696 public static final float FLOAT_COMPONENT_HEIGHT = Utils.asNan(ID_COMPONENT_HEIGHT); 697 698 /** ID_OFFSET_TO_UTC is the offset from UTC in sec (typically / 3600f) */ 699 public static final float FLOAT_OFFSET_TO_UTC = Utils.asNan(ID_OFFSET_TO_UTC); 700 701 /** TOUCH_POS_X is the x position of the touch */ 702 public static final float FLOAT_TOUCH_POS_X = Utils.asNan(ID_TOUCH_POS_X); 703 704 /** TOUCH_POS_Y is the y position of the touch */ 705 public static final float FLOAT_TOUCH_POS_Y = Utils.asNan(ID_TOUCH_POS_Y); 706 707 /** TOUCH_VEL_X is the x velocity of the touch */ 708 public static final float FLOAT_TOUCH_VEL_X = Utils.asNan(ID_TOUCH_VEL_X); 709 710 /** TOUCH_VEL_Y is the x velocity of the touch */ 711 public static final float FLOAT_TOUCH_VEL_Y = Utils.asNan(ID_TOUCH_VEL_Y); 712 713 /** TOUCH_EVENT_TIME the time of the touch */ 714 public static final float FLOAT_TOUCH_EVENT_TIME = Utils.asNan(ID_TOUCH_EVENT_TIME); 715 716 /** Animation time in seconds */ 717 public static final float FLOAT_ANIMATION_TIME = Utils.asNan(ID_ANIMATION_TIME); 718 719 /** Animation time in seconds */ 720 public static final float FLOAT_ANIMATION_DELTA_TIME = Utils.asNan(ID_ANIMATION_DELTA_TIME); 721 722 /** X acceleration sensor value in M/s^2 */ 723 public static final float FLOAT_ACCELERATION_X = Utils.asNan(ID_ACCELERATION_X); 724 725 /** Y acceleration sensor value in M/s^2 */ 726 public static final float FLOAT_ACCELERATION_Y = Utils.asNan(ID_ACCELERATION_Y); 727 728 /** Z acceleration sensor value in M/s^2 */ 729 public static final float FLOAT_ACCELERATION_Z = Utils.asNan(ID_ACCELERATION_Z); 730 731 /** X Gyroscope rotation rate sensor value in radians/second */ 732 public static final float FLOAT_GYRO_ROT_X = Utils.asNan(ID_GYRO_ROT_X); 733 734 /** Y Gyroscope rotation rate sensor value in radians/second */ 735 public static final float FLOAT_GYRO_ROT_Y = Utils.asNan(ID_GYRO_ROT_Y); 736 737 /** Z Gyroscope rotation rate sensor value in radians/second */ 738 public static final float FLOAT_GYRO_ROT_Z = Utils.asNan(ID_GYRO_ROT_Z); 739 740 /** Ambient magnetic field in X. sensor value in micro-Tesla (uT) */ 741 public static final float FLOAT_MAGNETIC_X = Utils.asNan(ID_MAGNETIC_X); 742 743 /** Ambient magnetic field in Y. sensor value in micro-Tesla (uT) */ 744 public static final float FLOAT_MAGNETIC_Y = Utils.asNan(ID_MAGNETIC_Y); 745 746 /** Ambient magnetic field in Z. sensor value in micro-Tesla (uT) */ 747 public static final float FLOAT_MAGNETIC_Z = Utils.asNan(ID_MAGNETIC_Z); 748 749 /** Ambient light level in SI lux */ 750 public static final float FLOAT_LIGHT = Utils.asNan(ID_LIGHT); 751 752 /** When was this player built */ 753 public static final float FLOAT_API_LEVEL = Utils.asNan(ID_API_LEVEL); 754 755 /** The default font size */ 756 public static final float FLOAT_FONT_SIZE = Utils.asNan(ID_FONT_SIZE); 757 758 /** The time in seconds since the epoch. */ 759 public static final long INT_EPOCH_SECOND = ((long) ID_EPOCH_SECOND) + 0x100000000L; 760 761 /////////////////////////////////////////////////////////////////////////////////////////////// 762 // Click handling 763 /////////////////////////////////////////////////////////////////////////////////////////////// 764 765 /** 766 * Is this a time id float 767 * 768 * @param fl the floatId to test 769 * @return true if it is a time id 770 */ isTime(float fl)771 public static boolean isTime(float fl) { 772 int value = Utils.idFromNan(fl); 773 return value >= ID_CONTINUOUS_SEC && value <= ID_DAY_OF_MONTH; 774 } 775 776 /** 777 * get the time from a float id that indicates a type of time 778 * 779 * @param fl id of the type of time information requested 780 * @return various time information such as seconds or min 781 */ getTime(float fl)782 public static float getTime(float fl) { 783 LocalDateTime dateTime = 784 LocalDateTime.now(ZoneId.systemDefault()); // TODO, pass in a timezone explicitly? 785 // This define the time in the format 786 // seconds run from Midnight=0 quantized to seconds hour 0..3599 787 // minutes run from Midnight=0 quantized to minutes 0..1439 788 // hours run from Midnight=0 quantized to Hours 0-23 789 // CONTINUOUS_SEC is seconds from midnight looping every hour 0-3600 790 // CONTINUOUS_SEC is accurate to milliseconds due to float precession 791 // ID_OFFSET_TO_UTC is the offset from UTC in sec (typically / 3600f) 792 int value = Utils.idFromNan(fl); 793 int month = dateTime.getMonth().getValue(); 794 int hour = dateTime.getHour(); 795 int minute = dateTime.getMinute(); 796 int seconds = dateTime.getSecond(); 797 int currentMinute = hour * 60 + minute; 798 int currentSeconds = minute * 60 + seconds; 799 float sec = currentSeconds + dateTime.getNano() * 1E-9f; 800 int day_week = dateTime.getDayOfWeek().getValue(); 801 802 ZoneId zone = ZoneId.systemDefault(); 803 OffsetDateTime offsetDateTime = dateTime.atZone(zone).toOffsetDateTime(); 804 ZoneOffset offset = offsetDateTime.getOffset(); 805 switch (value) { 806 case ID_OFFSET_TO_UTC: 807 return offset.getTotalSeconds(); 808 case ID_CONTINUOUS_SEC: 809 return sec; 810 case ID_TIME_IN_SEC: 811 return currentSeconds; 812 case ID_TIME_IN_MIN: 813 return currentMinute; 814 case ID_TIME_IN_HR: 815 return hour; 816 case ID_CALENDAR_MONTH: 817 case ID_DAY_OF_MONTH: 818 return month; 819 case ID_WEEK_DAY: 820 return day_week; 821 } 822 return fl; 823 } 824 825 /** 826 * Add a click area to the doc 827 * 828 * @param id the id of the click area 829 * @param contentDescription the content description of the click area 830 * @param left the left bounds of the click area 831 * @param top the top bounds of the click area 832 * @param right the right bounds of the click area 833 * @param bottom the 834 * @param metadataId the id of the metadata string 835 */ addClickArea( int id, int contentDescription, float left, float top, float right, float bottom, int metadataId)836 public abstract void addClickArea( 837 int id, 838 int contentDescription, 839 float left, 840 float top, 841 float right, 842 float bottom, 843 int metadataId); 844 845 /** increments the count of operations executed in a pass */ incrementOpCount()846 public void incrementOpCount() { 847 mOpCount++; 848 if (mOpCount > MAX_OP_COUNT) { 849 throw new RuntimeException("Too many operations executed"); 850 } 851 } 852 853 /** 854 * Get the last Op Count and clear the count. 855 * 856 * @return the number of ops executed. 857 */ getLastOpCount()858 public int getLastOpCount() { 859 int count = mOpCount; 860 mOpCount = 0; 861 return count; 862 } 863 864 /** Explicitly clear the operation counter */ clearLastOpCount()865 public void clearLastOpCount() { 866 mOpCount = 0; 867 } 868 } 869