1 /* 2 * Copyright (C) 2018 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package com.google.android.textclassifier; 18 19 import android.content.res.AssetFileDescriptor; 20 import java.util.Collection; 21 import java.util.concurrent.atomic.AtomicBoolean; 22 import javax.annotation.Nullable; 23 24 /** 25 * Java wrapper for Annotator native library interface. This library is used for detecting entities 26 * in text. 27 * 28 * @hide 29 */ 30 public final class AnnotatorModel implements AutoCloseable { 31 private final AtomicBoolean isClosed = new AtomicBoolean(false); 32 33 static { 34 System.loadLibrary("textclassifier"); 35 } 36 37 // Keep these in sync with the constants defined in AOSP. 38 static final String TYPE_UNKNOWN = ""; 39 static final String TYPE_OTHER = "other"; 40 static final String TYPE_EMAIL = "email"; 41 static final String TYPE_PHONE = "phone"; 42 static final String TYPE_ADDRESS = "address"; 43 static final String TYPE_URL = "url"; 44 static final String TYPE_DATE = "date"; 45 static final String TYPE_DATE_TIME = "datetime"; 46 static final String TYPE_FLIGHT_NUMBER = "flight"; 47 48 public static final double INVALID_LATITUDE = 180; 49 public static final double INVALID_LONGITUDE = 360; 50 public static final float INVALID_LOCATION_ACCURACY_METERS = 0; 51 52 private long annotatorPtr; 53 // To tell GC to keep the LangID model alive at least as long as this object. 54 @Nullable private LangIdModel langIdModel; 55 56 /** Enumeration for specifying the usecase of the annotations. */ 57 public static enum AnnotationUsecase { 58 /** Results are optimized for Smart{Select,Share,Linkify}. */ 59 SMART(0), 60 61 /** 62 * Results are optimized for using TextClassifier as an infrastructure that annotates as much as 63 * possible. 64 */ 65 RAW(1); 66 67 private final int value; 68 AnnotationUsecase(int value)69 AnnotationUsecase(int value) { 70 this.value = value; 71 } 72 getValue()73 public int getValue() { 74 return value; 75 } 76 }; 77 78 /** Enumeration for specifying the annotate mode. */ 79 public static enum AnnotateMode { 80 /** Result contains entity annotation for each input fragment. */ 81 ENTITY_ANNOTATION(0), 82 83 /** Result will include both entity annotation and topicality annotation. */ 84 ENTITY_AND_TOPICALITY_ANNOTATION(1); 85 86 private final int value; 87 AnnotateMode(int value)88 AnnotateMode(int value) { 89 this.value = value; 90 } 91 getValue()92 public int getValue() { 93 return value; 94 } 95 }; 96 97 /** 98 * Creates a new instance of SmartSelect predictor, using the provided model image, given as a 99 * file descriptor. 100 */ AnnotatorModel(int fileDescriptor)101 public AnnotatorModel(int fileDescriptor) { 102 annotatorPtr = nativeNewAnnotator(fileDescriptor); 103 if (annotatorPtr == 0L) { 104 throw new IllegalArgumentException("Couldn't initialize TC from file descriptor."); 105 } 106 } 107 108 /** 109 * Creates a new instance of SmartSelect predictor, using the provided model image, given as a 110 * file path. 111 */ AnnotatorModel(String path)112 public AnnotatorModel(String path) { 113 annotatorPtr = nativeNewAnnotatorFromPath(path); 114 if (annotatorPtr == 0L) { 115 throw new IllegalArgumentException("Couldn't initialize TC from given file."); 116 } 117 } 118 119 /** 120 * Creates a new instance of SmartSelect predictor, using the provided model image, given as an 121 * {@link AssetFileDescriptor}. 122 */ AnnotatorModel(AssetFileDescriptor assetFileDescriptor)123 public AnnotatorModel(AssetFileDescriptor assetFileDescriptor) { 124 annotatorPtr = 125 nativeNewAnnotatorWithOffset( 126 assetFileDescriptor.getParcelFileDescriptor().getFd(), 127 assetFileDescriptor.getStartOffset(), 128 assetFileDescriptor.getLength()); 129 if (annotatorPtr == 0L) { 130 throw new IllegalArgumentException("Couldn't initialize TC from asset file descriptor."); 131 } 132 } 133 134 /** Initializes the knowledge engine, passing the given serialized config to it. */ initializeKnowledgeEngine(byte[] serializedConfig)135 public void initializeKnowledgeEngine(byte[] serializedConfig) { 136 if (!nativeInitializeKnowledgeEngine(annotatorPtr, serializedConfig)) { 137 throw new IllegalArgumentException("Couldn't initialize the KG engine"); 138 } 139 } 140 141 /** Initializes the contact engine, passing the given serialized config to it. */ initializeContactEngine(byte[] serializedConfig)142 public void initializeContactEngine(byte[] serializedConfig) { 143 if (!nativeInitializeContactEngine(annotatorPtr, serializedConfig)) { 144 throw new IllegalArgumentException("Couldn't initialize the contact engine"); 145 } 146 } 147 148 /** Initializes the installed app engine, passing the given serialized config to it. */ initializeInstalledAppEngine(byte[] serializedConfig)149 public void initializeInstalledAppEngine(byte[] serializedConfig) { 150 if (!nativeInitializeInstalledAppEngine(annotatorPtr, serializedConfig)) { 151 throw new IllegalArgumentException("Couldn't initialize the installed app engine"); 152 } 153 } 154 155 /** 156 * Sets the LangId model to the annotator. Do not call close on the given LangIdModel object 157 * before this object is closed. Also, this object does not take the memory ownership of the given 158 * LangIdModel object. 159 */ setLangIdModel(@ullable LangIdModel langIdModel)160 public void setLangIdModel(@Nullable LangIdModel langIdModel) { 161 this.langIdModel = langIdModel; 162 nativeSetLangId(annotatorPtr, langIdModel == null ? 0 : langIdModel.getNativePointer()); 163 } 164 165 /** 166 * Initializes the person name engine, using the provided model image, given as an {@link 167 * AssetFileDescriptor}. 168 */ initializePersonNameEngine(AssetFileDescriptor assetFileDescriptor)169 public void initializePersonNameEngine(AssetFileDescriptor assetFileDescriptor) { 170 if (!nativeInitializePersonNameEngine( 171 annotatorPtr, 172 assetFileDescriptor.getParcelFileDescriptor().getFd(), 173 assetFileDescriptor.getStartOffset(), 174 assetFileDescriptor.getLength())) { 175 throw new IllegalArgumentException("Couldn't initialize the person name engine"); 176 } 177 } 178 179 /** 180 * Given a string context and current selection, computes the selection suggestion. 181 * 182 * <p>The begin and end are character indices into the context UTF8 string. selectionBegin is the 183 * character index where the selection begins, and selectionEnd is the index of one character past 184 * the selection span. 185 * 186 * <p>The return value is an array of two ints: suggested selection beginning and end, with the 187 * same semantics as the input selectionBeginning and selectionEnd. 188 */ suggestSelection( String context, int selectionBegin, int selectionEnd, SelectionOptions options)189 public int[] suggestSelection( 190 String context, int selectionBegin, int selectionEnd, SelectionOptions options) { 191 return nativeSuggestSelection(annotatorPtr, context, selectionBegin, selectionEnd, options); 192 } 193 194 /** 195 * Given a string context and current selection, classifies the type of the selected text. 196 * 197 * <p>The begin and end params are character indices in the context string. 198 * 199 * <p>Returns an array of ClassificationResult objects with the probability scores for different 200 * collections. 201 */ classifyText( String context, int selectionBegin, int selectionEnd, ClassificationOptions options)202 public ClassificationResult[] classifyText( 203 String context, int selectionBegin, int selectionEnd, ClassificationOptions options) { 204 return classifyText( 205 context, 206 selectionBegin, 207 selectionEnd, 208 options, 209 /*appContext=*/ null, 210 /*resourcesLocale=*/ null); 211 } 212 classifyText( String context, int selectionBegin, int selectionEnd, ClassificationOptions options, Object appContext, String resourcesLocale)213 public ClassificationResult[] classifyText( 214 String context, 215 int selectionBegin, 216 int selectionEnd, 217 ClassificationOptions options, 218 Object appContext, 219 String resourcesLocale) { 220 return nativeClassifyText( 221 annotatorPtr, context, selectionBegin, selectionEnd, options, appContext, resourcesLocale); 222 } 223 224 /** 225 * Annotates given input text. The annotations should cover the whole input context except for 226 * whitespaces, and are sorted by their position in the context string. 227 */ annotate(String text, AnnotationOptions options)228 public AnnotatedSpan[] annotate(String text, AnnotationOptions options) { 229 return nativeAnnotate(annotatorPtr, text, options); 230 } 231 232 /** 233 * Annotates multiple fragments of text at once. There will be one AnnotatedSpan array for each 234 * input fragment to annotate. 235 */ annotateStructuredInput(InputFragment[] fragments, AnnotationOptions options)236 public Annotations annotateStructuredInput(InputFragment[] fragments, AnnotationOptions options) { 237 return nativeAnnotateStructuredInput(annotatorPtr, fragments, options); 238 } 239 240 /** 241 * Looks up a knowledge entity by its identifier. Returns null if the entity is not found or on 242 * error. 243 */ lookUpKnowledgeEntity(String id)244 public byte[] lookUpKnowledgeEntity(String id) { 245 return nativeLookUpKnowledgeEntity(annotatorPtr, id); 246 } 247 248 /** Frees up the allocated memory. */ 249 @Override close()250 public void close() { 251 if (isClosed.compareAndSet(false, true)) { 252 nativeCloseAnnotator(annotatorPtr); 253 annotatorPtr = 0L; 254 } 255 } 256 257 @Override finalize()258 protected void finalize() throws Throwable { 259 try { 260 close(); 261 } finally { 262 super.finalize(); 263 } 264 } 265 266 /** Returns a comma separated list of locales supported by the model as BCP 47 tags. */ getLocales(int fd)267 public static String getLocales(int fd) { 268 return nativeGetLocales(fd); 269 } 270 271 /** Returns a comma separated list of locales supported by the model as BCP 47 tags. */ getLocales(AssetFileDescriptor assetFileDescriptor)272 public static String getLocales(AssetFileDescriptor assetFileDescriptor) { 273 return nativeGetLocalesWithOffset( 274 assetFileDescriptor.getParcelFileDescriptor().getFd(), 275 assetFileDescriptor.getStartOffset(), 276 assetFileDescriptor.getLength()); 277 } 278 279 /** Returns the version of the model. */ getVersion(int fd)280 public static int getVersion(int fd) { 281 return nativeGetVersion(fd); 282 } 283 284 /** Returns the version of the model. */ getVersion(AssetFileDescriptor assetFileDescriptor)285 public static int getVersion(AssetFileDescriptor assetFileDescriptor) { 286 return nativeGetVersionWithOffset( 287 assetFileDescriptor.getParcelFileDescriptor().getFd(), 288 assetFileDescriptor.getStartOffset(), 289 assetFileDescriptor.getLength()); 290 } 291 292 /** Returns the name of the model. */ getName(int fd)293 public static String getName(int fd) { 294 return nativeGetName(fd); 295 } 296 297 /** Returns the name of the model. */ getName(AssetFileDescriptor assetFileDescriptor)298 public static String getName(AssetFileDescriptor assetFileDescriptor) { 299 return nativeGetNameWithOffset( 300 assetFileDescriptor.getParcelFileDescriptor().getFd(), 301 assetFileDescriptor.getStartOffset(), 302 assetFileDescriptor.getLength()); 303 } 304 305 /** Information about a parsed time/date. */ 306 public static final class DatetimeResult { 307 308 public static final int GRANULARITY_YEAR = 0; 309 public static final int GRANULARITY_MONTH = 1; 310 public static final int GRANULARITY_WEEK = 2; 311 public static final int GRANULARITY_DAY = 3; 312 public static final int GRANULARITY_HOUR = 4; 313 public static final int GRANULARITY_MINUTE = 5; 314 public static final int GRANULARITY_SECOND = 6; 315 316 private final long timeMsUtc; 317 private final int granularity; 318 DatetimeResult(long timeMsUtc, int granularity)319 public DatetimeResult(long timeMsUtc, int granularity) { 320 this.timeMsUtc = timeMsUtc; 321 this.granularity = granularity; 322 } 323 getTimeMsUtc()324 public long getTimeMsUtc() { 325 return timeMsUtc; 326 } 327 getGranularity()328 public int getGranularity() { 329 return granularity; 330 } 331 } 332 333 /** Classification result for classifyText method. */ 334 public static final class ClassificationResult { 335 private final String collection; 336 private final float score; 337 @Nullable private final DatetimeResult datetimeResult; 338 @Nullable private final byte[] serializedKnowledgeResult; 339 @Nullable private final String contactName; 340 @Nullable private final String contactGivenName; 341 @Nullable private final String contactFamilyName; 342 @Nullable private final String contactNickname; 343 @Nullable private final String contactEmailAddress; 344 @Nullable private final String contactPhoneNumber; 345 @Nullable private final String contactAccountType; 346 @Nullable private final String contactAccountName; 347 @Nullable private final String contactId; 348 @Nullable private final String appName; 349 @Nullable private final String appPackageName; 350 @Nullable private final NamedVariant[] entityData; 351 @Nullable private final byte[] serializedEntityData; 352 @Nullable private final RemoteActionTemplate[] remoteActionTemplates; 353 private final long durationMs; 354 private final long numericValue; 355 private final double numericDoubleValue; 356 ClassificationResult( String collection, float score, @Nullable DatetimeResult datetimeResult, @Nullable byte[] serializedKnowledgeResult, @Nullable String contactName, @Nullable String contactGivenName, @Nullable String contactFamilyName, @Nullable String contactNickname, @Nullable String contactEmailAddress, @Nullable String contactPhoneNumber, @Nullable String contactAccountType, @Nullable String contactAccountName, @Nullable String contactId, @Nullable String appName, @Nullable String appPackageName, @Nullable NamedVariant[] entityData, @Nullable byte[] serializedEntityData, @Nullable RemoteActionTemplate[] remoteActionTemplates, long durationMs, long numericValue, double numericDoubleValue)357 public ClassificationResult( 358 String collection, 359 float score, 360 @Nullable DatetimeResult datetimeResult, 361 @Nullable byte[] serializedKnowledgeResult, 362 @Nullable String contactName, 363 @Nullable String contactGivenName, 364 @Nullable String contactFamilyName, 365 @Nullable String contactNickname, 366 @Nullable String contactEmailAddress, 367 @Nullable String contactPhoneNumber, 368 @Nullable String contactAccountType, 369 @Nullable String contactAccountName, 370 @Nullable String contactId, 371 @Nullable String appName, 372 @Nullable String appPackageName, 373 @Nullable NamedVariant[] entityData, 374 @Nullable byte[] serializedEntityData, 375 @Nullable RemoteActionTemplate[] remoteActionTemplates, 376 long durationMs, 377 long numericValue, 378 double numericDoubleValue) { 379 this.collection = collection; 380 this.score = score; 381 this.datetimeResult = datetimeResult; 382 this.serializedKnowledgeResult = serializedKnowledgeResult; 383 this.contactName = contactName; 384 this.contactGivenName = contactGivenName; 385 this.contactFamilyName = contactFamilyName; 386 this.contactNickname = contactNickname; 387 this.contactEmailAddress = contactEmailAddress; 388 this.contactPhoneNumber = contactPhoneNumber; 389 this.contactAccountType = contactAccountType; 390 this.contactAccountName = contactAccountName; 391 this.contactId = contactId; 392 this.appName = appName; 393 this.appPackageName = appPackageName; 394 this.entityData = entityData; 395 this.serializedEntityData = serializedEntityData; 396 this.remoteActionTemplates = remoteActionTemplates; 397 this.durationMs = durationMs; 398 this.numericValue = numericValue; 399 this.numericDoubleValue = numericDoubleValue; 400 } 401 402 /** Returns the classified entity type. */ getCollection()403 public String getCollection() { 404 return collection; 405 } 406 407 /** Confidence score between 0 and 1. */ getScore()408 public float getScore() { 409 return score; 410 } 411 412 @Nullable getDatetimeResult()413 public DatetimeResult getDatetimeResult() { 414 return datetimeResult; 415 } 416 417 @Nullable getSerializedKnowledgeResult()418 public byte[] getSerializedKnowledgeResult() { 419 return serializedKnowledgeResult; 420 } 421 422 @Nullable getContactName()423 public String getContactName() { 424 return contactName; 425 } 426 427 @Nullable getContactGivenName()428 public String getContactGivenName() { 429 return contactGivenName; 430 } 431 432 @Nullable getContactFamilyName()433 public String getContactFamilyName() { 434 return contactFamilyName; 435 } 436 437 @Nullable getContactNickname()438 public String getContactNickname() { 439 return contactNickname; 440 } 441 442 @Nullable getContactEmailAddress()443 public String getContactEmailAddress() { 444 return contactEmailAddress; 445 } 446 447 @Nullable getContactPhoneNumber()448 public String getContactPhoneNumber() { 449 return contactPhoneNumber; 450 } 451 452 @Nullable getContactAccountType()453 public String getContactAccountType() { 454 return contactAccountType; 455 } 456 457 @Nullable getContactAccountName()458 public String getContactAccountName() { 459 return contactAccountName; 460 } 461 462 @Nullable getContactId()463 public String getContactId() { 464 return contactId; 465 } 466 467 @Nullable getAppName()468 public String getAppName() { 469 return appName; 470 } 471 472 @Nullable getAppPackageName()473 public String getAppPackageName() { 474 return appPackageName; 475 } 476 477 @Nullable getEntityData()478 public NamedVariant[] getEntityData() { 479 return entityData; 480 } 481 482 @Nullable getSerializedEntityData()483 public byte[] getSerializedEntityData() { 484 return serializedEntityData; 485 } 486 487 @Nullable getRemoteActionTemplates()488 public RemoteActionTemplate[] getRemoteActionTemplates() { 489 return remoteActionTemplates; 490 } 491 getDurationMs()492 public long getDurationMs() { 493 return durationMs; 494 } 495 getNumericValue()496 public long getNumericValue() { 497 return numericValue; 498 } 499 getNumericDoubleValue()500 public double getNumericDoubleValue() { 501 return numericDoubleValue; 502 } 503 } 504 505 /** Represents a result of Annotate call. */ 506 public static final class AnnotatedSpan { 507 private final int startIndex; 508 private final int endIndex; 509 private final ClassificationResult[] classification; 510 AnnotatedSpan(int startIndex, int endIndex, ClassificationResult[] classification)511 AnnotatedSpan(int startIndex, int endIndex, ClassificationResult[] classification) { 512 this.startIndex = startIndex; 513 this.endIndex = endIndex; 514 this.classification = classification; 515 } 516 getStartIndex()517 public int getStartIndex() { 518 return startIndex; 519 } 520 getEndIndex()521 public int getEndIndex() { 522 return endIndex; 523 } 524 getClassification()525 public ClassificationResult[] getClassification() { 526 return classification; 527 } 528 } 529 530 /** 531 * Represents a result of Annotate call, which will include both entity annotations and topicality 532 * annotations. 533 */ 534 public static final class Annotations { 535 private final AnnotatedSpan[][] annotatedSpans; 536 private final ClassificationResult[] topicalityResults; 537 Annotations(AnnotatedSpan[][] annotatedSpans, ClassificationResult[] topicalityResults)538 Annotations(AnnotatedSpan[][] annotatedSpans, ClassificationResult[] topicalityResults) { 539 this.annotatedSpans = annotatedSpans; 540 this.topicalityResults = topicalityResults; 541 } 542 getAnnotatedSpans()543 public AnnotatedSpan[][] getAnnotatedSpans() { 544 return annotatedSpans; 545 } 546 getTopicalityResults()547 public ClassificationResult[] getTopicalityResults() { 548 return topicalityResults; 549 } 550 } 551 552 /** Represents a fragment of text to the AnnotateStructuredInput call. */ 553 public static final class InputFragment { 554 555 /** Encapsulates the data required to set the relative time of an InputFragment. */ 556 public static final class DatetimeOptions { 557 private final String referenceTimezone; 558 private final Long referenceTimeMsUtc; 559 DatetimeOptions(String referenceTimezone, Long referenceTimeMsUtc)560 public DatetimeOptions(String referenceTimezone, Long referenceTimeMsUtc) { 561 this.referenceTimeMsUtc = referenceTimeMsUtc; 562 this.referenceTimezone = referenceTimezone; 563 } 564 } 565 InputFragment(String text)566 public InputFragment(String text) { 567 this.text = text; 568 this.datetimeOptionsNullable = null; 569 this.boundingBoxTop = 0; 570 this.boundingBoxHeight = 0; 571 } 572 InputFragment( String text, DatetimeOptions datetimeOptions, float boundingBoxTop, float boundingBoxHeight)573 public InputFragment( 574 String text, 575 DatetimeOptions datetimeOptions, 576 float boundingBoxTop, 577 float boundingBoxHeight) { 578 this.text = text; 579 this.datetimeOptionsNullable = datetimeOptions; 580 this.boundingBoxTop = boundingBoxTop; 581 this.boundingBoxHeight = boundingBoxHeight; 582 } 583 584 private final String text; 585 // The DatetimeOptions can't be Optional because the _api16 build of the TCLib SDK does not 586 // support java.util.Optional. 587 private final DatetimeOptions datetimeOptionsNullable; 588 private final float boundingBoxTop; 589 private final float boundingBoxHeight; 590 getText()591 public String getText() { 592 return text; 593 } 594 getBoundingBoxTop()595 public float getBoundingBoxTop() { 596 return boundingBoxTop; 597 } 598 getBoundingBoxHeight()599 public float getBoundingBoxHeight() { 600 return boundingBoxHeight; 601 } 602 hasDatetimeOptions()603 public boolean hasDatetimeOptions() { 604 return datetimeOptionsNullable != null; 605 } 606 getReferenceTimeMsUtc()607 public long getReferenceTimeMsUtc() { 608 return datetimeOptionsNullable.referenceTimeMsUtc; 609 } 610 getReferenceTimezone()611 public String getReferenceTimezone() { 612 return datetimeOptionsNullable.referenceTimezone; 613 } 614 } 615 616 /** Represents options for the suggestSelection call. */ 617 public static final class SelectionOptions { 618 @Nullable private final String locales; 619 @Nullable private final String detectedTextLanguageTags; 620 private final int annotationUsecase; 621 private final double userLocationLat; 622 private final double userLocationLng; 623 private final float userLocationAccuracyMeters; 624 private final boolean usePodNer; 625 private final boolean useVocabAnnotator; 626 SelectionOptions( @ullable String locales, @Nullable String detectedTextLanguageTags, int annotationUsecase, double userLocationLat, double userLocationLng, float userLocationAccuracyMeters, boolean usePodNer, boolean useVocabAnnotator)627 private SelectionOptions( 628 @Nullable String locales, 629 @Nullable String detectedTextLanguageTags, 630 int annotationUsecase, 631 double userLocationLat, 632 double userLocationLng, 633 float userLocationAccuracyMeters, 634 boolean usePodNer, 635 boolean useVocabAnnotator) { 636 this.locales = locales; 637 this.detectedTextLanguageTags = detectedTextLanguageTags; 638 this.annotationUsecase = annotationUsecase; 639 this.userLocationLat = userLocationLat; 640 this.userLocationLng = userLocationLng; 641 this.userLocationAccuracyMeters = userLocationAccuracyMeters; 642 this.usePodNer = usePodNer; 643 this.useVocabAnnotator = useVocabAnnotator; 644 } 645 646 /** Can be used to build a SelectionsOptions instance. */ 647 public static class Builder { 648 @Nullable private String locales; 649 @Nullable private String detectedTextLanguageTags; 650 private int annotationUsecase = AnnotationUsecase.SMART.getValue(); 651 private double userLocationLat = INVALID_LATITUDE; 652 private double userLocationLng = INVALID_LONGITUDE; 653 private float userLocationAccuracyMeters = INVALID_LOCATION_ACCURACY_METERS; 654 private boolean usePodNer = true; 655 private boolean useVocabAnnotator = true; 656 setLocales(@ullable String locales)657 public Builder setLocales(@Nullable String locales) { 658 this.locales = locales; 659 return this; 660 } 661 setDetectedTextLanguageTags(@ullable String detectedTextLanguageTags)662 public Builder setDetectedTextLanguageTags(@Nullable String detectedTextLanguageTags) { 663 this.detectedTextLanguageTags = detectedTextLanguageTags; 664 return this; 665 } 666 setAnnotationUsecase(int annotationUsecase)667 public Builder setAnnotationUsecase(int annotationUsecase) { 668 this.annotationUsecase = annotationUsecase; 669 return this; 670 } 671 setUserLocationLat(double userLocationLat)672 public Builder setUserLocationLat(double userLocationLat) { 673 this.userLocationLat = userLocationLat; 674 return this; 675 } 676 setUserLocationLng(double userLocationLng)677 public Builder setUserLocationLng(double userLocationLng) { 678 this.userLocationLng = userLocationLng; 679 return this; 680 } 681 setUserLocationAccuracyMeters(float userLocationAccuracyMeters)682 public Builder setUserLocationAccuracyMeters(float userLocationAccuracyMeters) { 683 this.userLocationAccuracyMeters = userLocationAccuracyMeters; 684 return this; 685 } 686 setUsePodNer(boolean usePodNer)687 public Builder setUsePodNer(boolean usePodNer) { 688 this.usePodNer = usePodNer; 689 return this; 690 } 691 setUseVocabAnnotator(boolean useVocabAnnotator)692 public Builder setUseVocabAnnotator(boolean useVocabAnnotator) { 693 this.useVocabAnnotator = useVocabAnnotator; 694 return this; 695 } 696 build()697 public SelectionOptions build() { 698 return new SelectionOptions( 699 locales, 700 detectedTextLanguageTags, 701 annotationUsecase, 702 userLocationLat, 703 userLocationLng, 704 userLocationAccuracyMeters, 705 usePodNer, 706 useVocabAnnotator); 707 } 708 } 709 builder()710 public static Builder builder() { 711 return new Builder(); 712 } 713 714 @Nullable getLocales()715 public String getLocales() { 716 return locales; 717 } 718 719 /** Returns a comma separated list of BCP 47 language tags. */ 720 @Nullable getDetectedTextLanguageTags()721 public String getDetectedTextLanguageTags() { 722 return detectedTextLanguageTags; 723 } 724 getAnnotationUsecase()725 public int getAnnotationUsecase() { 726 return annotationUsecase; 727 } 728 getUserLocationLat()729 public double getUserLocationLat() { 730 return userLocationLat; 731 } 732 getUserLocationLng()733 public double getUserLocationLng() { 734 return userLocationLng; 735 } 736 getUserLocationAccuracyMeters()737 public float getUserLocationAccuracyMeters() { 738 return userLocationAccuracyMeters; 739 } 740 getUsePodNer()741 public boolean getUsePodNer() { 742 return usePodNer; 743 } 744 getUseVocabAnnotator()745 public boolean getUseVocabAnnotator() { 746 return useVocabAnnotator; 747 } 748 } 749 750 /** Represents options for the classifyText call. */ 751 public static final class ClassificationOptions { 752 private final long referenceTimeMsUtc; 753 private final String referenceTimezone; 754 @Nullable private final String locales; 755 @Nullable private final String detectedTextLanguageTags; 756 private final int annotationUsecase; 757 private final double userLocationLat; 758 private final double userLocationLng; 759 private final float userLocationAccuracyMeters; 760 private final String userFamiliarLanguageTags; 761 private final boolean usePodNer; 762 private final boolean triggerDictionaryOnBeginnerWords; 763 private final boolean useVocabAnnotator; 764 ClassificationOptions( long referenceTimeMsUtc, String referenceTimezone, @Nullable String locales, @Nullable String detectedTextLanguageTags, int annotationUsecase, double userLocationLat, double userLocationLng, float userLocationAccuracyMeters, String userFamiliarLanguageTags, boolean usePodNer, boolean triggerDictionaryOnBeginnerWords, boolean useVocabAnnotator)765 private ClassificationOptions( 766 long referenceTimeMsUtc, 767 String referenceTimezone, 768 @Nullable String locales, 769 @Nullable String detectedTextLanguageTags, 770 int annotationUsecase, 771 double userLocationLat, 772 double userLocationLng, 773 float userLocationAccuracyMeters, 774 String userFamiliarLanguageTags, 775 boolean usePodNer, 776 boolean triggerDictionaryOnBeginnerWords, 777 boolean useVocabAnnotator) { 778 this.referenceTimeMsUtc = referenceTimeMsUtc; 779 this.referenceTimezone = referenceTimezone; 780 this.locales = locales; 781 this.detectedTextLanguageTags = detectedTextLanguageTags; 782 this.annotationUsecase = annotationUsecase; 783 this.userLocationLat = userLocationLat; 784 this.userLocationLng = userLocationLng; 785 this.userLocationAccuracyMeters = userLocationAccuracyMeters; 786 this.userFamiliarLanguageTags = userFamiliarLanguageTags; 787 this.usePodNer = usePodNer; 788 this.triggerDictionaryOnBeginnerWords = triggerDictionaryOnBeginnerWords; 789 this.useVocabAnnotator = useVocabAnnotator; 790 } 791 792 /** Can be used to build a ClassificationOptions instance. */ 793 public static class Builder { 794 private long referenceTimeMsUtc; 795 @Nullable private String referenceTimezone; 796 @Nullable private String locales; 797 @Nullable private String detectedTextLanguageTags; 798 private int annotationUsecase = AnnotationUsecase.SMART.getValue(); 799 private double userLocationLat = INVALID_LATITUDE; 800 private double userLocationLng = INVALID_LONGITUDE; 801 private float userLocationAccuracyMeters = INVALID_LOCATION_ACCURACY_METERS; 802 private String userFamiliarLanguageTags = ""; 803 private boolean usePodNer = true; 804 private boolean triggerDictionaryOnBeginnerWords = false; 805 private boolean useVocabAnnotator = true; 806 setReferenceTimeMsUtc(long referenceTimeMsUtc)807 public Builder setReferenceTimeMsUtc(long referenceTimeMsUtc) { 808 this.referenceTimeMsUtc = referenceTimeMsUtc; 809 return this; 810 } 811 setReferenceTimezone(String referenceTimezone)812 public Builder setReferenceTimezone(String referenceTimezone) { 813 this.referenceTimezone = referenceTimezone; 814 return this; 815 } 816 setLocales(@ullable String locales)817 public Builder setLocales(@Nullable String locales) { 818 this.locales = locales; 819 return this; 820 } 821 setDetectedTextLanguageTags(@ullable String detectedTextLanguageTags)822 public Builder setDetectedTextLanguageTags(@Nullable String detectedTextLanguageTags) { 823 this.detectedTextLanguageTags = detectedTextLanguageTags; 824 return this; 825 } 826 setAnnotationUsecase(int annotationUsecase)827 public Builder setAnnotationUsecase(int annotationUsecase) { 828 this.annotationUsecase = annotationUsecase; 829 return this; 830 } 831 setUserLocationLat(double userLocationLat)832 public Builder setUserLocationLat(double userLocationLat) { 833 this.userLocationLat = userLocationLat; 834 return this; 835 } 836 setUserLocationLng(double userLocationLng)837 public Builder setUserLocationLng(double userLocationLng) { 838 this.userLocationLng = userLocationLng; 839 return this; 840 } 841 setUserLocationAccuracyMeters(float userLocationAccuracyMeters)842 public Builder setUserLocationAccuracyMeters(float userLocationAccuracyMeters) { 843 this.userLocationAccuracyMeters = userLocationAccuracyMeters; 844 return this; 845 } 846 setUserFamiliarLanguageTags(String userFamiliarLanguageTags)847 public Builder setUserFamiliarLanguageTags(String userFamiliarLanguageTags) { 848 this.userFamiliarLanguageTags = userFamiliarLanguageTags; 849 return this; 850 } 851 setUsePodNer(boolean usePodNer)852 public Builder setUsePodNer(boolean usePodNer) { 853 this.usePodNer = usePodNer; 854 return this; 855 } 856 setTrigerringDictionaryOnBeginnerWords( boolean triggerDictionaryOnBeginnerWords)857 public Builder setTrigerringDictionaryOnBeginnerWords( 858 boolean triggerDictionaryOnBeginnerWords) { 859 this.triggerDictionaryOnBeginnerWords = triggerDictionaryOnBeginnerWords; 860 return this; 861 } 862 setUseVocabAnnotator(boolean useVocabAnnotator)863 public Builder setUseVocabAnnotator(boolean useVocabAnnotator) { 864 this.useVocabAnnotator = useVocabAnnotator; 865 return this; 866 } 867 build()868 public ClassificationOptions build() { 869 return new ClassificationOptions( 870 referenceTimeMsUtc, 871 referenceTimezone, 872 locales, 873 detectedTextLanguageTags, 874 annotationUsecase, 875 userLocationLat, 876 userLocationLng, 877 userLocationAccuracyMeters, 878 userFamiliarLanguageTags, 879 usePodNer, 880 triggerDictionaryOnBeginnerWords, 881 useVocabAnnotator); 882 } 883 } 884 builder()885 public static Builder builder() { 886 return new Builder(); 887 } 888 getReferenceTimeMsUtc()889 public long getReferenceTimeMsUtc() { 890 return referenceTimeMsUtc; 891 } 892 getReferenceTimezone()893 public String getReferenceTimezone() { 894 return referenceTimezone; 895 } 896 897 @Nullable getLocale()898 public String getLocale() { 899 return locales; 900 } 901 902 /** Returns a comma separated list of BCP 47 language tags. */ 903 @Nullable getDetectedTextLanguageTags()904 public String getDetectedTextLanguageTags() { 905 return detectedTextLanguageTags; 906 } 907 getAnnotationUsecase()908 public int getAnnotationUsecase() { 909 return annotationUsecase; 910 } 911 getUserLocationLat()912 public double getUserLocationLat() { 913 return userLocationLat; 914 } 915 getUserLocationLng()916 public double getUserLocationLng() { 917 return userLocationLng; 918 } 919 getUserLocationAccuracyMeters()920 public float getUserLocationAccuracyMeters() { 921 return userLocationAccuracyMeters; 922 } 923 getUserFamiliarLanguageTags()924 public String getUserFamiliarLanguageTags() { 925 return userFamiliarLanguageTags; 926 } 927 getUsePodNer()928 public boolean getUsePodNer() { 929 return usePodNer; 930 } 931 getTriggerDictionaryOnBeginnerWords()932 public boolean getTriggerDictionaryOnBeginnerWords() { 933 return triggerDictionaryOnBeginnerWords; 934 } 935 getUseVocabAnnotator()936 public boolean getUseVocabAnnotator() { 937 return useVocabAnnotator; 938 } 939 } 940 941 /** Represents options for the annotate call. */ 942 public static final class AnnotationOptions { 943 private final long referenceTimeMsUtc; 944 private final String referenceTimezone; 945 @Nullable private final String locales; 946 @Nullable private final String detectedTextLanguageTags; 947 private final String[] entityTypes; 948 private final int annotateMode; 949 private final int annotationUsecase; 950 private final boolean hasLocationPermission; 951 private final boolean hasPersonalizationPermission; 952 private final boolean isSerializedEntityDataEnabled; 953 private final double userLocationLat; 954 private final double userLocationLng; 955 private final float userLocationAccuracyMeters; 956 private final boolean usePodNer; 957 private final boolean triggerDictionaryOnBeginnerWords; 958 private final boolean useVocabAnnotator; 959 AnnotationOptions( long referenceTimeMsUtc, String referenceTimezone, @Nullable String locales, @Nullable String detectedTextLanguageTags, @Nullable Collection<String> entityTypes, int annotateMode, int annotationUsecase, boolean hasLocationPermission, boolean hasPersonalizationPermission, boolean isSerializedEntityDataEnabled, double userLocationLat, double userLocationLng, float userLocationAccuracyMeters, boolean usePodNer, boolean triggerDictionaryOnBeginnerWords, boolean useVocabAnnotator)960 private AnnotationOptions( 961 long referenceTimeMsUtc, 962 String referenceTimezone, 963 @Nullable String locales, 964 @Nullable String detectedTextLanguageTags, 965 @Nullable Collection<String> entityTypes, 966 int annotateMode, 967 int annotationUsecase, 968 boolean hasLocationPermission, 969 boolean hasPersonalizationPermission, 970 boolean isSerializedEntityDataEnabled, 971 double userLocationLat, 972 double userLocationLng, 973 float userLocationAccuracyMeters, 974 boolean usePodNer, 975 boolean triggerDictionaryOnBeginnerWords, 976 boolean useVocabAnnotator) { 977 this.referenceTimeMsUtc = referenceTimeMsUtc; 978 this.referenceTimezone = referenceTimezone; 979 this.locales = locales; 980 this.detectedTextLanguageTags = detectedTextLanguageTags; 981 this.entityTypes = entityTypes == null ? new String[0] : entityTypes.toArray(new String[0]); 982 this.annotateMode = annotateMode; 983 this.annotationUsecase = annotationUsecase; 984 this.isSerializedEntityDataEnabled = isSerializedEntityDataEnabled; 985 this.userLocationLat = userLocationLat; 986 this.userLocationLng = userLocationLng; 987 this.userLocationAccuracyMeters = userLocationAccuracyMeters; 988 this.hasLocationPermission = hasLocationPermission; 989 this.hasPersonalizationPermission = hasPersonalizationPermission; 990 this.usePodNer = usePodNer; 991 this.triggerDictionaryOnBeginnerWords = triggerDictionaryOnBeginnerWords; 992 this.useVocabAnnotator = useVocabAnnotator; 993 } 994 995 /** Can be used to build an AnnotationOptions instance. */ 996 public static class Builder { 997 private long referenceTimeMsUtc; 998 @Nullable private String referenceTimezone; 999 @Nullable private String locales; 1000 @Nullable private String detectedTextLanguageTags; 1001 @Nullable private Collection<String> entityTypes; 1002 private int annotateMode = AnnotateMode.ENTITY_ANNOTATION.getValue(); 1003 private int annotationUsecase = AnnotationUsecase.SMART.getValue(); 1004 private boolean hasLocationPermission = true; 1005 private boolean hasPersonalizationPermission = true; 1006 private boolean isSerializedEntityDataEnabled = false; 1007 private double userLocationLat = INVALID_LATITUDE; 1008 private double userLocationLng = INVALID_LONGITUDE; 1009 private float userLocationAccuracyMeters = INVALID_LOCATION_ACCURACY_METERS; 1010 private boolean usePodNer = true; 1011 private boolean triggerDictionaryOnBeginnerWords = false; 1012 private boolean useVocabAnnotator = true; 1013 setReferenceTimeMsUtc(long referenceTimeMsUtc)1014 public Builder setReferenceTimeMsUtc(long referenceTimeMsUtc) { 1015 this.referenceTimeMsUtc = referenceTimeMsUtc; 1016 return this; 1017 } 1018 setReferenceTimezone(String referenceTimezone)1019 public Builder setReferenceTimezone(String referenceTimezone) { 1020 this.referenceTimezone = referenceTimezone; 1021 return this; 1022 } 1023 setLocales(@ullable String locales)1024 public Builder setLocales(@Nullable String locales) { 1025 this.locales = locales; 1026 return this; 1027 } 1028 setDetectedTextLanguageTags(@ullable String detectedTextLanguageTags)1029 public Builder setDetectedTextLanguageTags(@Nullable String detectedTextLanguageTags) { 1030 this.detectedTextLanguageTags = detectedTextLanguageTags; 1031 return this; 1032 } 1033 setEntityTypes(Collection<String> entityTypes)1034 public Builder setEntityTypes(Collection<String> entityTypes) { 1035 this.entityTypes = entityTypes; 1036 return this; 1037 } 1038 setAnnotateMode(int annotateMode)1039 public Builder setAnnotateMode(int annotateMode) { 1040 this.annotateMode = annotateMode; 1041 return this; 1042 } 1043 setAnnotationUsecase(int annotationUsecase)1044 public Builder setAnnotationUsecase(int annotationUsecase) { 1045 this.annotationUsecase = annotationUsecase; 1046 return this; 1047 } 1048 setHasLocationPermission(boolean hasLocationPermission)1049 public Builder setHasLocationPermission(boolean hasLocationPermission) { 1050 this.hasLocationPermission = hasLocationPermission; 1051 return this; 1052 } 1053 setHasPersonalizationPermission(boolean hasPersonalizationPermission)1054 public Builder setHasPersonalizationPermission(boolean hasPersonalizationPermission) { 1055 this.hasPersonalizationPermission = hasPersonalizationPermission; 1056 return this; 1057 } 1058 setIsSerializedEntityDataEnabled(boolean isSerializedEntityDataEnabled)1059 public Builder setIsSerializedEntityDataEnabled(boolean isSerializedEntityDataEnabled) { 1060 this.isSerializedEntityDataEnabled = isSerializedEntityDataEnabled; 1061 return this; 1062 } 1063 setUserLocationLat(double userLocationLat)1064 public Builder setUserLocationLat(double userLocationLat) { 1065 this.userLocationLat = userLocationLat; 1066 return this; 1067 } 1068 setUserLocationLng(double userLocationLng)1069 public Builder setUserLocationLng(double userLocationLng) { 1070 this.userLocationLng = userLocationLng; 1071 return this; 1072 } 1073 setUserLocationAccuracyMeters(float userLocationAccuracyMeters)1074 public Builder setUserLocationAccuracyMeters(float userLocationAccuracyMeters) { 1075 this.userLocationAccuracyMeters = userLocationAccuracyMeters; 1076 return this; 1077 } 1078 setUsePodNer(boolean usePodNer)1079 public Builder setUsePodNer(boolean usePodNer) { 1080 this.usePodNer = usePodNer; 1081 return this; 1082 } 1083 setTriggerDictionaryOnBeginnerWords(boolean triggerDictionaryOnBeginnerWords)1084 public Builder setTriggerDictionaryOnBeginnerWords(boolean triggerDictionaryOnBeginnerWords) { 1085 this.triggerDictionaryOnBeginnerWords = triggerDictionaryOnBeginnerWords; 1086 return this; 1087 } 1088 setUseVocabAnnotator(boolean useVocabAnnotator)1089 public Builder setUseVocabAnnotator(boolean useVocabAnnotator) { 1090 this.useVocabAnnotator = useVocabAnnotator; 1091 return this; 1092 } 1093 build()1094 public AnnotationOptions build() { 1095 return new AnnotationOptions( 1096 referenceTimeMsUtc, 1097 referenceTimezone, 1098 locales, 1099 detectedTextLanguageTags, 1100 entityTypes, 1101 annotateMode, 1102 annotationUsecase, 1103 hasLocationPermission, 1104 hasPersonalizationPermission, 1105 isSerializedEntityDataEnabled, 1106 userLocationLat, 1107 userLocationLng, 1108 userLocationAccuracyMeters, 1109 usePodNer, 1110 triggerDictionaryOnBeginnerWords, 1111 useVocabAnnotator); 1112 } 1113 } 1114 builder()1115 public static Builder builder() { 1116 return new Builder(); 1117 } 1118 getReferenceTimeMsUtc()1119 public long getReferenceTimeMsUtc() { 1120 return referenceTimeMsUtc; 1121 } 1122 getReferenceTimezone()1123 public String getReferenceTimezone() { 1124 return referenceTimezone; 1125 } 1126 1127 @Nullable getLocale()1128 public String getLocale() { 1129 return locales; 1130 } 1131 1132 /** Returns a comma separated list of BCP 47 language tags. */ 1133 @Nullable getDetectedTextLanguageTags()1134 public String getDetectedTextLanguageTags() { 1135 return detectedTextLanguageTags; 1136 } 1137 getEntityTypes()1138 public String[] getEntityTypes() { 1139 return entityTypes; 1140 } 1141 getAnnotateMode()1142 public int getAnnotateMode() { 1143 return annotateMode; 1144 } 1145 getAnnotationUsecase()1146 public int getAnnotationUsecase() { 1147 return annotationUsecase; 1148 } 1149 isSerializedEntityDataEnabled()1150 public boolean isSerializedEntityDataEnabled() { 1151 return isSerializedEntityDataEnabled; 1152 } 1153 getUserLocationLat()1154 public double getUserLocationLat() { 1155 return userLocationLat; 1156 } 1157 getUserLocationLng()1158 public double getUserLocationLng() { 1159 return userLocationLng; 1160 } 1161 getUserLocationAccuracyMeters()1162 public float getUserLocationAccuracyMeters() { 1163 return userLocationAccuracyMeters; 1164 } 1165 hasLocationPermission()1166 public boolean hasLocationPermission() { 1167 return hasLocationPermission; 1168 } 1169 hasPersonalizationPermission()1170 public boolean hasPersonalizationPermission() { 1171 return hasPersonalizationPermission; 1172 } 1173 getUsePodNer()1174 public boolean getUsePodNer() { 1175 return usePodNer; 1176 } 1177 getTriggerDictionaryOnBeginnerWords()1178 public boolean getTriggerDictionaryOnBeginnerWords() { 1179 return triggerDictionaryOnBeginnerWords; 1180 } 1181 getUseVocabAnnotator()1182 public boolean getUseVocabAnnotator() { 1183 return useVocabAnnotator; 1184 } 1185 } 1186 1187 /** 1188 * Retrieves the pointer to the native object. Note: Need to keep the AnnotatorModel alive as long 1189 * as the pointer is used. 1190 */ getNativeAnnotatorPointer()1191 long getNativeAnnotatorPointer() { 1192 return nativeGetNativeModelPtr(annotatorPtr); 1193 } 1194 nativeNewAnnotator(int fd)1195 private static native long nativeNewAnnotator(int fd); 1196 nativeNewAnnotatorFromPath(String path)1197 private static native long nativeNewAnnotatorFromPath(String path); 1198 nativeNewAnnotatorWithOffset(int fd, long offset, long size)1199 private static native long nativeNewAnnotatorWithOffset(int fd, long offset, long size); 1200 nativeGetLocales(int fd)1201 private static native String nativeGetLocales(int fd); 1202 nativeGetLocalesWithOffset(int fd, long offset, long size)1203 private static native String nativeGetLocalesWithOffset(int fd, long offset, long size); 1204 nativeGetVersion(int fd)1205 private static native int nativeGetVersion(int fd); 1206 nativeGetVersionWithOffset(int fd, long offset, long size)1207 private static native int nativeGetVersionWithOffset(int fd, long offset, long size); 1208 nativeGetName(int fd)1209 private static native String nativeGetName(int fd); 1210 nativeGetNameWithOffset(int fd, long offset, long size)1211 private static native String nativeGetNameWithOffset(int fd, long offset, long size); 1212 nativeGetNativeModelPtr(long context)1213 private native long nativeGetNativeModelPtr(long context); 1214 nativeInitializeKnowledgeEngine(long context, byte[] serializedConfig)1215 private native boolean nativeInitializeKnowledgeEngine(long context, byte[] serializedConfig); 1216 nativeInitializeContactEngine(long context, byte[] serializedConfig)1217 private native boolean nativeInitializeContactEngine(long context, byte[] serializedConfig); 1218 nativeInitializeInstalledAppEngine(long context, byte[] serializedConfig)1219 private native boolean nativeInitializeInstalledAppEngine(long context, byte[] serializedConfig); 1220 nativeInitializePersonNameEngine( long context, int fd, long offset, long size)1221 private native boolean nativeInitializePersonNameEngine( 1222 long context, int fd, long offset, long size); 1223 nativeSetLangId(long annotatorPtr, long langIdPtr)1224 private native void nativeSetLangId(long annotatorPtr, long langIdPtr); 1225 nativeSuggestSelection( long context, String text, int selectionBegin, int selectionEnd, SelectionOptions options)1226 private native int[] nativeSuggestSelection( 1227 long context, String text, int selectionBegin, int selectionEnd, SelectionOptions options); 1228 nativeClassifyText( long context, String text, int selectionBegin, int selectionEnd, ClassificationOptions options, Object appContext, String resourceLocales)1229 private native ClassificationResult[] nativeClassifyText( 1230 long context, 1231 String text, 1232 int selectionBegin, 1233 int selectionEnd, 1234 ClassificationOptions options, 1235 Object appContext, 1236 String resourceLocales); 1237 nativeAnnotate( long context, String text, AnnotationOptions options)1238 private native AnnotatedSpan[] nativeAnnotate( 1239 long context, String text, AnnotationOptions options); 1240 nativeAnnotateStructuredInput( long context, InputFragment[] inputFragments, AnnotationOptions options)1241 private native Annotations nativeAnnotateStructuredInput( 1242 long context, InputFragment[] inputFragments, AnnotationOptions options); 1243 nativeLookUpKnowledgeEntity(long context, String id)1244 private native byte[] nativeLookUpKnowledgeEntity(long context, String id); 1245 nativeCloseAnnotator(long context)1246 private native void nativeCloseAnnotator(long context); 1247 } 1248