1 /*
2  * Copyright (C) 2021 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 android.view.translation;
18 
19 import android.annotation.NonNull;
20 import android.annotation.Nullable;
21 import android.os.Bundle;
22 import android.os.Parcel;
23 import android.os.Parcelable;
24 
25 import com.android.internal.util.DataClass;
26 
27 import java.util.Objects;
28 
29 /**
30  * A translated response value from {@link android.service.translation.TranslationService}.
31  */
32 @DataClass(genBuilder = true, genToString = true, genEqualsHashCode = true,
33         genHiddenConstDefs = true)
34 public final class TranslationResponseValue implements Parcelable {
35 
36     /**
37      * This value was successfully translated.
38      */
39     public static final int STATUS_SUCCESS = 0;
40     /**
41      * This value was not successfully translated. No value can be obtained with {@link #getText()}.
42      */
43     public static final int STATUS_ERROR = 1;
44 
45     /**
46      * Name in the result of {@link #getExtras()} to pass dictionary definitions of the text
47      * categorized by parts of speech.
48      *
49      * <p>The dictionary definitions consists of groups of terms keyed by their corresponding parts
50      * of speech. This map-like structure is stored in a {@link Bundle}. The individual parts of
51      * speech can be traversed by {@link Bundle#keySet()} and used to get the corresponding list
52      * of terms as {@link CharSequence}s.
53      *
54      * <ul>
55      *     <li>"noun" -> ["def1", "def2", ...]</li>
56      *     <li>"verb" -> ["def3", "def4", ...]</li>
57      *     <li>...</li>
58      * </ul>
59      *
60      * The set of parts of speech can then be used by
61      * {@link Bundle#getCharSequenceArrayList(String)} to get the list of terms.
62      *
63      * <b>Example</b>:
64      *
65      * {@code for (String partOfSpeech : extras.getBundle(EXTRA_DEFINITIONS).keySet()) {
66      *    ArrayList<CharSequence> terms =
67      *            extras.getBundle(EXTRA_DEFINITIONS).getCharSequenceArrayList(partOfSpeech);
68      *    ...
69      * }}</p>
70      */
71     public static final String EXTRA_DEFINITIONS = "android.view.translation.extra.DEFINITIONS";
72 
73     /**
74      * The status code of this {@link TranslationResponseValue}.
75      *
76      * <p>If the status code is {@link #STATUS_ERROR}, no values are attached, and all getters will
77      * return {@code null}.
78      */
79     private final @Status int mStatusCode;
80 
81     /**
82      * The translated text result.
83      */
84     @Nullable
85     private final CharSequence mText;
86 
87     /**
88      * Extra results associated with the translated text.
89      *
90      * <p>The bundle includes {@link #EXTRA_DEFINITIONS}, obtained by {@link Bundle#getBundle}.
91      * </p>
92      */
93     @NonNull
94     private final Bundle mExtras;
95 
96     // TODO: Add example of transliteration.
97     /**
98      * The transliteration result of the translated text.
99      *
100      * <p>This returns a CharSequence representation of the transliteration of the translated text.
101      */
102     @Nullable
103     private final CharSequence mTransliteration;
104 
105     /**
106      * Creates a {@link TranslationResponseValue} with the {@link #STATUS_ERROR} result;
107      */
108     @NonNull
forError()109     public static TranslationResponseValue forError() {
110         return new TranslationResponseValue(STATUS_ERROR, null, Bundle.EMPTY, null);
111     }
112 
defaultText()113     private static CharSequence defaultText() {
114         return null;
115     }
116 
defaultExtras()117     private static Bundle defaultExtras() {
118         return Bundle.EMPTY;
119     }
120 
extrasEquals(Bundle other)121     private boolean extrasEquals(Bundle other) {
122         // TODO: Also compare the contents.
123         return Objects.equals(mExtras, other) || (mExtras.isEmpty() && other.isEmpty());
124     }
125 
defaultTransliteration()126     private static CharSequence defaultTransliteration() {
127         return null;
128     }
129 
130     @DataClass.Suppress("setStatusCode")
131     abstract static class BaseBuilder {
132 
133     }
134 
135 
136 
137     // Code below generated by codegen v1.0.23.
138     //
139     // DO NOT MODIFY!
140     // CHECKSTYLE:OFF Generated code
141     //
142     // To regenerate run:
143     // $ codegen $ANDROID_BUILD_TOP/frameworks/base/core/java/android/view/translation/TranslationResponseValue.java
144     //
145     // To exclude the generated code from IntelliJ auto-formatting enable (one-time):
146     //   Settings > Editor > Code Style > Formatter Control
147     //@formatter:off
148 
149 
150     /** @hide */
151     @android.annotation.IntDef(prefix = "STATUS_", value = {
152         STATUS_SUCCESS,
153         STATUS_ERROR
154     })
155     @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.SOURCE)
156     @DataClass.Generated.Member
157     public @interface Status {}
158 
159     /** @hide */
160     @DataClass.Generated.Member
statusToString(@tatus int value)161     public static String statusToString(@Status int value) {
162         switch (value) {
163             case STATUS_SUCCESS:
164                     return "STATUS_SUCCESS";
165             case STATUS_ERROR:
166                     return "STATUS_ERROR";
167             default: return Integer.toHexString(value);
168         }
169     }
170 
171     @DataClass.Generated.Member
TranslationResponseValue( @tatus int statusCode, @Nullable CharSequence text, @NonNull Bundle extras, @Nullable CharSequence transliteration)172     /* package-private */ TranslationResponseValue(
173             @Status int statusCode,
174             @Nullable CharSequence text,
175             @NonNull Bundle extras,
176             @Nullable CharSequence transliteration) {
177         this.mStatusCode = statusCode;
178 
179         if (!(mStatusCode == STATUS_SUCCESS)
180                 && !(mStatusCode == STATUS_ERROR)) {
181             throw new java.lang.IllegalArgumentException(
182                     "statusCode was " + mStatusCode + " but must be one of: "
183                             + "STATUS_SUCCESS(" + STATUS_SUCCESS + "), "
184                             + "STATUS_ERROR(" + STATUS_ERROR + ")");
185         }
186 
187         this.mText = text;
188         this.mExtras = extras;
189         com.android.internal.util.AnnotationValidations.validate(
190                 NonNull.class, null, mExtras);
191         this.mTransliteration = transliteration;
192 
193         // onConstructed(); // You can define this method to get a callback
194     }
195 
196     /**
197      * The status code of this {@link TranslationResponseValue}.
198      *
199      * <p>If the status code is {@link #STATUS_ERROR}, no values are attached, and all getters will
200      * return {@code null}.
201      */
202     @DataClass.Generated.Member
getStatusCode()203     public @Status int getStatusCode() {
204         return mStatusCode;
205     }
206 
207     /**
208      * The translated text result.
209      */
210     @DataClass.Generated.Member
getText()211     public @Nullable CharSequence getText() {
212         return mText;
213     }
214 
215     /**
216      * Extra results associated with the translated text.
217      *
218      * <p>The bundle includes {@link #EXTRA_DEFINITIONS}, obtained by {@link Bundle#getBundle}.
219      * </p>
220      */
221     @DataClass.Generated.Member
getExtras()222     public @NonNull Bundle getExtras() {
223         return mExtras;
224     }
225 
226     /**
227      * The transliteration result of the translated text.
228      *
229      * <p>This returns a CharSequence representation of the transliteration of the translated text.
230      */
231     @DataClass.Generated.Member
getTransliteration()232     public @Nullable CharSequence getTransliteration() {
233         return mTransliteration;
234     }
235 
236     @Override
237     @DataClass.Generated.Member
toString()238     public String toString() {
239         // You can override field toString logic by defining methods like:
240         // String fieldNameToString() { ... }
241 
242         return "TranslationResponseValue { " +
243                 "statusCode = " + statusToString(mStatusCode) + ", " +
244                 "text = " + mText + ", " +
245                 "extras = " + mExtras + ", " +
246                 "transliteration = " + mTransliteration +
247         " }";
248     }
249 
250     @Override
251     @DataClass.Generated.Member
equals(@ullable Object o)252     public boolean equals(@Nullable Object o) {
253         // You can override field equality logic by defining either of the methods like:
254         // boolean fieldNameEquals(TranslationResponseValue other) { ... }
255         // boolean fieldNameEquals(FieldType otherValue) { ... }
256 
257         if (this == o) return true;
258         if (o == null || getClass() != o.getClass()) return false;
259         @SuppressWarnings("unchecked")
260         TranslationResponseValue that = (TranslationResponseValue) o;
261         //noinspection PointlessBooleanExpression
262         return true
263                 && mStatusCode == that.mStatusCode
264                 && Objects.equals(mText, that.mText)
265                 && extrasEquals(that.mExtras)
266                 && Objects.equals(mTransliteration, that.mTransliteration);
267     }
268 
269     @Override
270     @DataClass.Generated.Member
hashCode()271     public int hashCode() {
272         // You can override field hashCode logic by defining methods like:
273         // int fieldNameHashCode() { ... }
274 
275         int _hash = 1;
276         _hash = 31 * _hash + mStatusCode;
277         _hash = 31 * _hash + Objects.hashCode(mText);
278         _hash = 31 * _hash + Objects.hashCode(mExtras);
279         _hash = 31 * _hash + Objects.hashCode(mTransliteration);
280         return _hash;
281     }
282 
283     @Override
284     @DataClass.Generated.Member
writeToParcel(@onNull Parcel dest, int flags)285     public void writeToParcel(@NonNull Parcel dest, int flags) {
286         // You can override field parcelling by defining methods like:
287         // void parcelFieldName(Parcel dest, int flags) { ... }
288 
289         byte flg = 0;
290         if (mText != null) flg |= 0x2;
291         if (mTransliteration != null) flg |= 0x8;
292         dest.writeByte(flg);
293         dest.writeInt(mStatusCode);
294         if (mText != null) dest.writeCharSequence(mText);
295         dest.writeBundle(mExtras);
296         if (mTransliteration != null) dest.writeCharSequence(mTransliteration);
297     }
298 
299     @Override
300     @DataClass.Generated.Member
describeContents()301     public int describeContents() { return 0; }
302 
303     /** @hide */
304     @SuppressWarnings({"unchecked", "RedundantCast"})
305     @DataClass.Generated.Member
TranslationResponseValue(@onNull Parcel in)306     /* package-private */ TranslationResponseValue(@NonNull Parcel in) {
307         // You can override field unparcelling by defining methods like:
308         // static FieldType unparcelFieldName(Parcel in) { ... }
309 
310         byte flg = in.readByte();
311         int statusCode = in.readInt();
312         CharSequence text = (flg & 0x2) == 0 ? null : (CharSequence) in.readCharSequence();
313         Bundle extras = in.readBundle();
314         CharSequence transliteration = (flg & 0x8) == 0 ? null : (CharSequence) in.readCharSequence();
315 
316         this.mStatusCode = statusCode;
317 
318         if (!(mStatusCode == STATUS_SUCCESS)
319                 && !(mStatusCode == STATUS_ERROR)) {
320             throw new java.lang.IllegalArgumentException(
321                     "statusCode was " + mStatusCode + " but must be one of: "
322                             + "STATUS_SUCCESS(" + STATUS_SUCCESS + "), "
323                             + "STATUS_ERROR(" + STATUS_ERROR + ")");
324         }
325 
326         this.mText = text;
327         this.mExtras = extras;
328         com.android.internal.util.AnnotationValidations.validate(
329                 NonNull.class, null, mExtras);
330         this.mTransliteration = transliteration;
331 
332         // onConstructed(); // You can define this method to get a callback
333     }
334 
335     @DataClass.Generated.Member
336     public static final @NonNull Parcelable.Creator<TranslationResponseValue> CREATOR
337             = new Parcelable.Creator<TranslationResponseValue>() {
338         @Override
339         public TranslationResponseValue[] newArray(int size) {
340             return new TranslationResponseValue[size];
341         }
342 
343         @Override
344         public TranslationResponseValue createFromParcel(@NonNull Parcel in) {
345             return new TranslationResponseValue(in);
346         }
347     };
348 
349     /**
350      * A builder for {@link TranslationResponseValue}
351      */
352     @SuppressWarnings("WeakerAccess")
353     @DataClass.Generated.Member
354     public static final class Builder extends BaseBuilder {
355 
356         private @Status int mStatusCode;
357         private @Nullable CharSequence mText;
358         private @NonNull Bundle mExtras;
359         private @Nullable CharSequence mTransliteration;
360 
361         private long mBuilderFieldsSet = 0L;
362 
363         /**
364          * Creates a new Builder.
365          *
366          * @param statusCode
367          *   The status code of this {@link TranslationResponseValue}.
368          *
369          *   <p>If the status code is {@link #STATUS_ERROR}, no values are attached, and all getters will
370          *   return {@code null}.
371          */
Builder( @tatus int statusCode)372         public Builder(
373                 @Status int statusCode) {
374             mStatusCode = statusCode;
375 
376             if (!(mStatusCode == STATUS_SUCCESS)
377                     && !(mStatusCode == STATUS_ERROR)) {
378                 throw new java.lang.IllegalArgumentException(
379                         "statusCode was " + mStatusCode + " but must be one of: "
380                                 + "STATUS_SUCCESS(" + STATUS_SUCCESS + "), "
381                                 + "STATUS_ERROR(" + STATUS_ERROR + ")");
382             }
383 
384         }
385 
386         /**
387          * The translated text result.
388          */
389         @DataClass.Generated.Member
setText(@onNull CharSequence value)390         public @NonNull Builder setText(@NonNull CharSequence value) {
391             checkNotUsed();
392             mBuilderFieldsSet |= 0x2;
393             mText = value;
394             return this;
395         }
396 
397         /**
398          * Extra results associated with the translated text.
399          *
400          * <p>The bundle includes {@link #EXTRA_DEFINITIONS}, obtained by {@link Bundle#getBundle}.
401          * </p>
402          */
403         @DataClass.Generated.Member
setExtras(@onNull Bundle value)404         public @NonNull Builder setExtras(@NonNull Bundle value) {
405             checkNotUsed();
406             mBuilderFieldsSet |= 0x4;
407             mExtras = value;
408             return this;
409         }
410 
411         /**
412          * The transliteration result of the translated text.
413          *
414          * <p>This returns a CharSequence representation of the transliteration of the translated text.
415          */
416         @DataClass.Generated.Member
setTransliteration(@onNull CharSequence value)417         public @NonNull Builder setTransliteration(@NonNull CharSequence value) {
418             checkNotUsed();
419             mBuilderFieldsSet |= 0x8;
420             mTransliteration = value;
421             return this;
422         }
423 
424         /** Builds the instance. This builder should not be touched after calling this! */
build()425         public @NonNull TranslationResponseValue build() {
426             checkNotUsed();
427             mBuilderFieldsSet |= 0x10; // Mark builder used
428 
429             if ((mBuilderFieldsSet & 0x2) == 0) {
430                 mText = defaultText();
431             }
432             if ((mBuilderFieldsSet & 0x4) == 0) {
433                 mExtras = defaultExtras();
434             }
435             if ((mBuilderFieldsSet & 0x8) == 0) {
436                 mTransliteration = defaultTransliteration();
437             }
438             TranslationResponseValue o = new TranslationResponseValue(
439                     mStatusCode,
440                     mText,
441                     mExtras,
442                     mTransliteration);
443             return o;
444         }
445 
checkNotUsed()446         private void checkNotUsed() {
447             if ((mBuilderFieldsSet & 0x10) != 0) {
448                 throw new IllegalStateException(
449                         "This Builder should not be reused. Use a new Builder instance instead");
450             }
451         }
452     }
453 
454     @DataClass.Generated(
455             time = 1631057245846L,
456             codegenVersion = "1.0.23",
457             sourceFile = "frameworks/base/core/java/android/view/translation/TranslationResponseValue.java",
458             inputSignatures = "public static final  int STATUS_SUCCESS\npublic static final  int STATUS_ERROR\npublic static final  java.lang.String EXTRA_DEFINITIONS\nprivate final @android.view.translation.TranslationResponseValue.Status int mStatusCode\nprivate final @android.annotation.Nullable java.lang.CharSequence mText\nprivate final @android.annotation.NonNull android.os.Bundle mExtras\nprivate final @android.annotation.Nullable java.lang.CharSequence mTransliteration\npublic static @android.annotation.NonNull android.view.translation.TranslationResponseValue forError()\nprivate static  java.lang.CharSequence defaultText()\nprivate static  android.os.Bundle defaultExtras()\nprivate  boolean extrasEquals(android.os.Bundle)\nprivate static  java.lang.CharSequence defaultTransliteration()\nclass TranslationResponseValue extends java.lang.Object implements [android.os.Parcelable]\nclass BaseBuilder extends java.lang.Object implements []\n@com.android.internal.util.DataClass(genBuilder=true, genToString=true, genEqualsHashCode=true, genHiddenConstDefs=true)\nclass BaseBuilder extends java.lang.Object implements []")
459     @Deprecated
__metadata()460     private void __metadata() {}
461 
462 
463     //@formatter:on
464     // End of generated code
465 
466 }
467