blob: 4c72474435a422586934ca102a821131539fa7a2 [file] [log] [blame]
Feng Cao04830a32019-11-13 00:45:19 -08001/*
2 * Copyright (C) 2019 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
17package android.view.inputmethod;
18
Feng Caodeec8f02020-03-10 18:14:13 -070019import android.annotation.BinderThread;
Feng Cao04830a32019-11-13 00:45:19 -080020import android.annotation.CallbackExecutor;
Feng Caob46851c2020-04-29 18:22:49 -070021import android.annotation.MainThread;
Feng Cao04830a32019-11-13 00:45:19 -080022import android.annotation.NonNull;
23import android.annotation.Nullable;
Joanne Chung2e707602020-01-09 18:14:49 +080024import android.annotation.TestApi;
Feng Cao04830a32019-11-13 00:45:19 -080025import android.content.Context;
Feng Caob46851c2020-04-29 18:22:49 -070026import android.os.Handler;
27import android.os.Looper;
Joanne Chung332c6a92020-02-07 17:10:23 +080028import android.os.Parcel;
Feng Cao04830a32019-11-13 00:45:19 -080029import android.os.Parcelable;
30import android.os.RemoteException;
31import android.util.Size;
32import android.util.Slog;
TYM Tsaib1f42dd2020-02-13 16:57:47 +080033import android.view.SurfaceControlViewHost;
Feng Caobd26abb2020-04-24 11:35:58 -070034import android.view.ViewGroup;
Adam Hef27433a2020-03-25 15:11:18 -070035import android.widget.inline.InlineContentView;
Feng Cao04830a32019-11-13 00:45:19 -080036
37import com.android.internal.util.DataClass;
Joanne Chung332c6a92020-02-07 17:10:23 +080038import com.android.internal.util.Parcelling;
Feng Cao04830a32019-11-13 00:45:19 -080039import com.android.internal.view.inline.IInlineContentCallback;
40import com.android.internal.view.inline.IInlineContentProvider;
41
42import java.lang.ref.WeakReference;
43import java.util.concurrent.Executor;
44import java.util.function.Consumer;
45
46/**
Feng Caob46851c2020-04-29 18:22:49 -070047 * This class represents an inline suggestion which is made by one app and can be embedded into the
48 * UI of another. Suggestions may contain sensitive information not known to the host app which
49 * needs to be protected from spoofing. To address that the suggestion view inflated on demand for
50 * embedding is created in such a way that the hosting app cannot introspect its content and cannot
51 * interact with it.
Feng Cao04830a32019-11-13 00:45:19 -080052 */
Feng Caob46851c2020-04-29 18:22:49 -070053@DataClass(genEqualsHashCode = true, genToString = true, genHiddenConstDefs = true,
Feng Cao04830a32019-11-13 00:45:19 -080054 genHiddenConstructor = true)
Feng Cao04830a32019-11-13 00:45:19 -080055public final class InlineSuggestion implements Parcelable {
56
57 private static final String TAG = "InlineSuggestion";
58
Feng Caob46851c2020-04-29 18:22:49 -070059 @NonNull
60 private final InlineSuggestionInfo mInfo;
Feng Cao04830a32019-11-13 00:45:19 -080061
Feng Caob46851c2020-04-29 18:22:49 -070062 /**
63 * @hide
64 */
65 @Nullable
66 private final IInlineContentProvider mContentProvider;
Feng Cao04830a32019-11-13 00:45:19 -080067
68 /**
Joanne Chung332c6a92020-02-07 17:10:23 +080069 * Used to keep a strong reference to the callback so it doesn't get garbage collected.
70 *
71 * @hide
72 */
73 @DataClass.ParcelWith(InlineContentCallbackImplParceling.class)
Feng Caob46851c2020-04-29 18:22:49 -070074 @Nullable
75 private InlineContentCallbackImpl mInlineContentCallback;
Joanne Chung332c6a92020-02-07 17:10:23 +080076
77 /**
Joanne Chung2e707602020-01-09 18:14:49 +080078 * Creates a new {@link InlineSuggestion}, for testing purpose.
79 *
80 * @hide
81 */
82 @TestApi
83 @NonNull
84 public static InlineSuggestion newInlineSuggestion(@NonNull InlineSuggestionInfo info) {
Joanne Chung332c6a92020-02-07 17:10:23 +080085 return new InlineSuggestion(info, null, /* inlineContentCallback */ null);
Joanne Chung2e707602020-01-09 18:14:49 +080086 }
87
Joanne Chung332c6a92020-02-07 17:10:23 +080088 /**
89 * Creates a new {@link InlineSuggestion}.
90 *
91 * @hide
92 */
Feng Caob46851c2020-04-29 18:22:49 -070093 public InlineSuggestion(@NonNull InlineSuggestionInfo info,
Joanne Chung332c6a92020-02-07 17:10:23 +080094 @Nullable IInlineContentProvider contentProvider) {
95 this(info, contentProvider, /* inlineContentCallback */ null);
96 }
Joanne Chung2e707602020-01-09 18:14:49 +080097
Joanne Chung2e707602020-01-09 18:14:49 +080098 /**
Feng Cao04830a32019-11-13 00:45:19 -080099 * Inflates a view with the content of this suggestion at a specific size.
Feng Caobd26abb2020-04-24 11:35:58 -0700100 *
Feng Caob46851c2020-04-29 18:22:49 -0700101 * <p> Each dimension of the size must satisfy one of the following conditions:
102 *
103 * <ol>
104 * <li>between {@link android.widget.inline.InlinePresentationSpec#getMinSize()} and
105 * {@link android.widget.inline.InlinePresentationSpec#getMaxSize()} of the presentation spec
106 * from {@code mInfo}
107 * <li>{@link ViewGroup.LayoutParams#WRAP_CONTENT}
108 * </ol>
109 *
110 * If the size is set to {@link
111 * ViewGroup.LayoutParams#WRAP_CONTENT}, then the size of the inflated view will be just large
112 * enough to fit the content, while still conforming to the min / max size specified by the
113 * {@link android.widget.inline.InlinePresentationSpec}.
Feng Cao04830a32019-11-13 00:45:19 -0800114 *
Svet Ganova57dadd2020-03-18 23:30:16 -0700115 * <p> The caller can attach an {@link android.view.View.OnClickListener} and/or an
Feng Caob46851c2020-04-29 18:22:49 -0700116 * {@link android.view.View.OnLongClickListener} to the view in the {@code callback} to receive
117 * click and long click events on the view.
Joanne Chung332c6a92020-02-07 17:10:23 +0800118 *
Feng Caodeec8f02020-03-10 18:14:13 -0700119 * @param context Context in which to inflate the view.
Feng Caob46851c2020-04-29 18:22:49 -0700120 * @param size The size at which to inflate the suggestion. For each dimension, it maybe an
121 * exact value or {@link ViewGroup.LayoutParams#WRAP_CONTENT}.
122 * @param callback Callback for receiving the inflated view, where the {@link
123 * ViewGroup.LayoutParams} of the view is set as the actual size of the
124 * underlying remote view.
Joanne Chung332c6a92020-02-07 17:10:23 +0800125 * @throws IllegalArgumentException If an invalid argument is passed.
Feng Caodeec8f02020-03-10 18:14:13 -0700126 * @throws IllegalStateException If this method is already called.
Feng Cao04830a32019-11-13 00:45:19 -0800127 */
128 public void inflate(@NonNull Context context, @NonNull Size size,
129 @NonNull @CallbackExecutor Executor callbackExecutor,
Svet Ganova57dadd2020-03-18 23:30:16 -0700130 @NonNull Consumer<InlineContentView> callback) {
Adam Hef27433a2020-03-25 15:11:18 -0700131 final Size minSize = mInfo.getInlinePresentationSpec().getMinSize();
132 final Size maxSize = mInfo.getInlinePresentationSpec().getMaxSize();
Feng Caobd26abb2020-04-24 11:35:58 -0700133 if (!isValid(size.getWidth(), minSize.getWidth(), maxSize.getWidth())
134 || !isValid(size.getHeight(), minSize.getHeight(), maxSize.getHeight())) {
135 throw new IllegalArgumentException(
136 "size is neither between min:" + minSize + " and max:" + maxSize
137 + ", nor wrap_content");
Feng Cao04830a32019-11-13 00:45:19 -0800138 }
Joanne Chung332c6a92020-02-07 17:10:23 +0800139 mInlineContentCallback = getInlineContentCallback(context, callbackExecutor, callback);
Feng Caob46851c2020-04-29 18:22:49 -0700140 if (mContentProvider == null) {
141 callbackExecutor.execute(() -> callback.accept(/* view */ null));
142 return;
143 }
144 try {
145 mContentProvider.provideContent(size.getWidth(), size.getHeight(),
146 new InlineContentCallbackWrapper(mInlineContentCallback));
147 } catch (RemoteException e) {
148 Slog.w(TAG, "Error creating suggestion content surface: " + e);
149 callbackExecutor.execute(() -> callback.accept(/* view */ null));
150 }
Feng Cao04830a32019-11-13 00:45:19 -0800151 }
152
Feng Caobd26abb2020-04-24 11:35:58 -0700153 /**
154 * Returns true if the {@code actual} length is within [min, max] or is {@link
155 * ViewGroup.LayoutParams#WRAP_CONTENT}.
156 */
157 private static boolean isValid(int actual, int min, int max) {
158 if (actual == ViewGroup.LayoutParams.WRAP_CONTENT) {
159 return true;
160 }
161 return actual >= min && actual <= max;
162 }
163
Joanne Chung332c6a92020-02-07 17:10:23 +0800164 private synchronized InlineContentCallbackImpl getInlineContentCallback(Context context,
Svet Ganova57dadd2020-03-18 23:30:16 -0700165 Executor callbackExecutor, Consumer<InlineContentView> callback) {
Joanne Chung332c6a92020-02-07 17:10:23 +0800166 if (mInlineContentCallback != null) {
167 throw new IllegalStateException("Already called #inflate()");
168 }
Feng Caob46851c2020-04-29 18:22:49 -0700169 return new InlineContentCallbackImpl(context, mContentProvider, callbackExecutor,
170 callback);
Joanne Chung332c6a92020-02-07 17:10:23 +0800171 }
172
Feng Caob46851c2020-04-29 18:22:49 -0700173 /**
174 * A wrapper class around the {@link InlineContentCallbackImpl} to ensure it's not strongly
175 * reference by the remote system server process.
176 */
Feng Cao04830a32019-11-13 00:45:19 -0800177 private static final class InlineContentCallbackWrapper extends IInlineContentCallback.Stub {
178
179 private final WeakReference<InlineContentCallbackImpl> mCallbackImpl;
180
181 InlineContentCallbackWrapper(InlineContentCallbackImpl callbackImpl) {
182 mCallbackImpl = new WeakReference<>(callbackImpl);
183 }
184
185 @Override
Feng Caodeec8f02020-03-10 18:14:13 -0700186 @BinderThread
Feng Caobd26abb2020-04-24 11:35:58 -0700187 public void onContent(SurfaceControlViewHost.SurfacePackage content, int width,
188 int height) {
Feng Cao04830a32019-11-13 00:45:19 -0800189 final InlineContentCallbackImpl callbackImpl = mCallbackImpl.get();
190 if (callbackImpl != null) {
Feng Caobd26abb2020-04-24 11:35:58 -0700191 callbackImpl.onContent(content, width, height);
Feng Cao04830a32019-11-13 00:45:19 -0800192 }
193 }
Feng Caodeec8f02020-03-10 18:14:13 -0700194
195 @Override
196 @BinderThread
197 public void onClick() {
198 final InlineContentCallbackImpl callbackImpl = mCallbackImpl.get();
199 if (callbackImpl != null) {
200 callbackImpl.onClick();
201 }
202 }
203
204 @Override
205 @BinderThread
206 public void onLongClick() {
207 final InlineContentCallbackImpl callbackImpl = mCallbackImpl.get();
208 if (callbackImpl != null) {
209 callbackImpl.onLongClick();
210 }
211 }
Feng Cao04830a32019-11-13 00:45:19 -0800212 }
213
Feng Caob46851c2020-04-29 18:22:49 -0700214 /**
215 * Handles the communication between the inline suggestion view in current (IME) process and
216 * the remote view provided from the system server.
217 *
218 * <p>This class is thread safe, because all the outside calls are piped into a single
219 * handler thread to be processed.
220 */
Feng Cao04830a32019-11-13 00:45:19 -0800221 private static final class InlineContentCallbackImpl {
222
Feng Caob46851c2020-04-29 18:22:49 -0700223 @NonNull
224 private final Handler mMainHandler = new Handler(Looper.getMainLooper());
225
226 @NonNull
227 private final Context mContext;
228 @Nullable
229 private final IInlineContentProvider mInlineContentProvider;
230 @NonNull
231 private final Executor mCallbackExecutor;
232
233 /**
234 * Callback from the client (IME) that will receive the inflated suggestion view. It'll
235 * only be called once when the view SurfacePackage is first sent back to the client. Any
236 * updates to the view due to attach to window and detach from window events will be
237 * handled under the hood, transparent from the client.
238 */
239 @NonNull
240 private final Consumer<InlineContentView> mCallback;
241
242 /**
243 * Indicates whether the first content has been received or not.
244 */
245 private boolean mFirstContentReceived = false;
246
247 /**
248 * The client (IME) side view which internally wraps a remote view. It'll be set when
249 * {@link #onContent(SurfaceControlViewHost.SurfacePackage, int, int)} is called, which
250 * should only happen once in the lifecycle of this inline suggestion instance.
251 */
252 @Nullable
253 private InlineContentView mView;
254
255 /**
256 * The SurfacePackage pointing to the remote view. It's cached here to be sent to the next
257 * available consumer.
258 */
259 @Nullable
260 private SurfaceControlViewHost.SurfacePackage mSurfacePackage;
261
262 /**
263 * The callback (from the {@link InlineContentView}) which consumes the surface package.
264 * It's cached here to be called when the SurfacePackage is returned from the remote
265 * view owning process.
266 */
267 @Nullable
268 private Consumer<SurfaceControlViewHost.SurfacePackage> mSurfacePackageConsumer;
Feng Cao04830a32019-11-13 00:45:19 -0800269
270 InlineContentCallbackImpl(@NonNull Context context,
Feng Caob46851c2020-04-29 18:22:49 -0700271 @Nullable IInlineContentProvider inlineContentProvider,
Feng Cao04830a32019-11-13 00:45:19 -0800272 @NonNull @CallbackExecutor Executor callbackExecutor,
Svet Ganova57dadd2020-03-18 23:30:16 -0700273 @NonNull Consumer<InlineContentView> callback) {
Feng Cao04830a32019-11-13 00:45:19 -0800274 mContext = context;
Feng Caob46851c2020-04-29 18:22:49 -0700275 mInlineContentProvider = inlineContentProvider;
Feng Cao04830a32019-11-13 00:45:19 -0800276 mCallbackExecutor = callbackExecutor;
277 mCallback = callback;
278 }
279
Feng Caodeec8f02020-03-10 18:14:13 -0700280 @BinderThread
Feng Caobd26abb2020-04-24 11:35:58 -0700281 public void onContent(SurfaceControlViewHost.SurfacePackage content, int width,
282 int height) {
Feng Caob46851c2020-04-29 18:22:49 -0700283 mMainHandler.post(() -> handleOnContent(content, width, height));
284 }
285
286 @MainThread
287 private void handleOnContent(SurfaceControlViewHost.SurfacePackage content, int width,
288 int height) {
289 if (!mFirstContentReceived) {
290 handleOnFirstContentReceived(content, width, height);
291 mFirstContentReceived = true;
292 } else {
293 handleOnSurfacePackage(content);
294 }
295 }
296
297 /**
298 * Called when the view content is returned for the first time.
299 */
300 @MainThread
301 private void handleOnFirstContentReceived(SurfaceControlViewHost.SurfacePackage content,
302 int width, int height) {
303 mSurfacePackage = content;
304 if (mSurfacePackage == null) {
Feng Cao04830a32019-11-13 00:45:19 -0800305 mCallbackExecutor.execute(() -> mCallback.accept(/* view */null));
306 } else {
Svet Ganova57dadd2020-03-18 23:30:16 -0700307 mView = new InlineContentView(mContext);
Feng Caobd26abb2020-04-24 11:35:58 -0700308 mView.setLayoutParams(new ViewGroup.LayoutParams(width, height));
Feng Caob46851c2020-04-29 18:22:49 -0700309 mView.setChildSurfacePackageUpdater(getSurfacePackageUpdater());
Feng Caodeec8f02020-03-10 18:14:13 -0700310 mCallbackExecutor.execute(() -> mCallback.accept(mView));
311 }
312 }
313
Feng Caob46851c2020-04-29 18:22:49 -0700314 /**
315 * Called when any subsequent SurfacePackage is returned from the remote view owning
316 * process.
317 */
318 @MainThread
319 private void handleOnSurfacePackage(SurfaceControlViewHost.SurfacePackage surfacePackage) {
320 mSurfacePackage = surfacePackage;
321 if (mSurfacePackage != null && mSurfacePackageConsumer != null) {
322 mSurfacePackageConsumer.accept(mSurfacePackage);
323 mSurfacePackageConsumer = null;
324 }
325 }
326
327 @MainThread
328 private void handleOnSurfacePackageReleased() {
329 mSurfacePackage = null;
330 try {
331 mInlineContentProvider.onSurfacePackageReleased();
332 } catch (RemoteException e) {
333 Slog.w(TAG, "Error calling onSurfacePackageReleased(): " + e);
334 }
335 }
336
337 @MainThread
338 private void handleGetSurfacePackage(
339 Consumer<SurfaceControlViewHost.SurfacePackage> consumer) {
340 if (mSurfacePackage != null) {
341 consumer.accept(mSurfacePackage);
342 } else {
343 mSurfacePackageConsumer = consumer;
344 try {
345 mInlineContentProvider.requestSurfacePackage();
346 } catch (RemoteException e) {
347 Slog.w(TAG, "Error calling getSurfacePackage(): " + e);
348 consumer.accept(null);
349 mSurfacePackageConsumer = null;
350 }
351 }
352 }
353
354 private InlineContentView.SurfacePackageUpdater getSurfacePackageUpdater() {
355 return new InlineContentView.SurfacePackageUpdater() {
356 @Override
357 public void onSurfacePackageReleased() {
358 mMainHandler.post(
359 () -> InlineContentCallbackImpl.this.handleOnSurfacePackageReleased());
360 }
361
362 @Override
363 public void getSurfacePackage(
364 Consumer<SurfaceControlViewHost.SurfacePackage> consumer) {
365 mMainHandler.post(
366 () -> InlineContentCallbackImpl.this.handleGetSurfacePackage(consumer));
367 }
368 };
369 }
370
Feng Caodeec8f02020-03-10 18:14:13 -0700371 @BinderThread
372 public void onClick() {
Feng Caob46851c2020-04-29 18:22:49 -0700373 mMainHandler.post(() -> {
374 if (mView != null && mView.hasOnClickListeners()) {
375 mView.callOnClick();
376 }
377 });
Feng Caodeec8f02020-03-10 18:14:13 -0700378 }
379
380 @BinderThread
381 public void onLongClick() {
Feng Caob46851c2020-04-29 18:22:49 -0700382 mMainHandler.post(() -> {
383 if (mView != null && mView.hasOnLongClickListeners()) {
384 mView.performLongClick();
385 }
386 });
Feng Cao04830a32019-11-13 00:45:19 -0800387 }
388 }
389
Joanne Chung332c6a92020-02-07 17:10:23 +0800390 /**
391 * This class used to provide parcelling logic for InlineContentCallbackImpl. It's intended to
392 * make this parcelling a no-op, since it can't be parceled and we don't need to parcel it.
393 */
394 private static class InlineContentCallbackImplParceling implements
395 Parcelling<InlineContentCallbackImpl> {
396 @Override
397 public void parcel(InlineContentCallbackImpl item, Parcel dest, int parcelFlags) {
398 }
399
400 @Override
401 public InlineContentCallbackImpl unparcel(Parcel source) {
402 return null;
403 }
404 }
405
Feng Cao04830a32019-11-13 00:45:19 -0800406
407
Feng Caob46851c2020-04-29 18:22:49 -0700408
Feng Caodeec8f02020-03-10 18:14:13 -0700409 // Code below generated by codegen v1.0.15.
Feng Cao04830a32019-11-13 00:45:19 -0800410 //
411 // DO NOT MODIFY!
412 // CHECKSTYLE:OFF Generated code
413 //
414 // To regenerate run:
415 // $ codegen $ANDROID_BUILD_TOP/frameworks/base/core/java/android/view/inputmethod/InlineSuggestion.java
416 //
417 // To exclude the generated code from IntelliJ auto-formatting enable (one-time):
418 // Settings > Editor > Code Style > Formatter Control
419 //@formatter:off
420
421
422 /**
423 * Creates a new InlineSuggestion.
424 *
Joanne Chung332c6a92020-02-07 17:10:23 +0800425 * @param inlineContentCallback
426 * Used to keep a strong reference to the callback so it doesn't get garbage collected.
Feng Cao04830a32019-11-13 00:45:19 -0800427 * @hide
428 */
429 @DataClass.Generated.Member
430 public InlineSuggestion(
431 @NonNull InlineSuggestionInfo info,
Joanne Chung332c6a92020-02-07 17:10:23 +0800432 @Nullable IInlineContentProvider contentProvider,
433 @Nullable InlineContentCallbackImpl inlineContentCallback) {
Feng Cao04830a32019-11-13 00:45:19 -0800434 this.mInfo = info;
435 com.android.internal.util.AnnotationValidations.validate(
436 NonNull.class, null, mInfo);
437 this.mContentProvider = contentProvider;
Joanne Chung332c6a92020-02-07 17:10:23 +0800438 this.mInlineContentCallback = inlineContentCallback;
Feng Cao04830a32019-11-13 00:45:19 -0800439
440 // onConstructed(); // You can define this method to get a callback
441 }
442
443 @DataClass.Generated.Member
444 public @NonNull InlineSuggestionInfo getInfo() {
445 return mInfo;
446 }
447
Joanne Chung332c6a92020-02-07 17:10:23 +0800448 /**
Feng Caob46851c2020-04-29 18:22:49 -0700449 * @hide
450 */
451 @DataClass.Generated.Member
452 public @Nullable IInlineContentProvider getContentProvider() {
453 return mContentProvider;
454 }
455
456 /**
Joanne Chung332c6a92020-02-07 17:10:23 +0800457 * Used to keep a strong reference to the callback so it doesn't get garbage collected.
458 *
459 * @hide
460 */
461 @DataClass.Generated.Member
462 public @Nullable InlineContentCallbackImpl getInlineContentCallback() {
463 return mInlineContentCallback;
464 }
465
Feng Cao04830a32019-11-13 00:45:19 -0800466 @Override
467 @DataClass.Generated.Member
468 public String toString() {
469 // You can override field toString logic by defining methods like:
470 // String fieldNameToString() { ... }
471
472 return "InlineSuggestion { " +
473 "info = " + mInfo + ", " +
Joanne Chung332c6a92020-02-07 17:10:23 +0800474 "contentProvider = " + mContentProvider + ", " +
475 "inlineContentCallback = " + mInlineContentCallback +
Feng Cao04830a32019-11-13 00:45:19 -0800476 " }";
477 }
478
479 @Override
480 @DataClass.Generated.Member
481 public boolean equals(@Nullable Object o) {
482 // You can override field equality logic by defining either of the methods like:
483 // boolean fieldNameEquals(InlineSuggestion other) { ... }
484 // boolean fieldNameEquals(FieldType otherValue) { ... }
485
486 if (this == o) return true;
487 if (o == null || getClass() != o.getClass()) return false;
488 @SuppressWarnings("unchecked")
489 InlineSuggestion that = (InlineSuggestion) o;
490 //noinspection PointlessBooleanExpression
491 return true
492 && java.util.Objects.equals(mInfo, that.mInfo)
Joanne Chung332c6a92020-02-07 17:10:23 +0800493 && java.util.Objects.equals(mContentProvider, that.mContentProvider)
494 && java.util.Objects.equals(mInlineContentCallback, that.mInlineContentCallback);
Feng Cao04830a32019-11-13 00:45:19 -0800495 }
496
497 @Override
498 @DataClass.Generated.Member
499 public int hashCode() {
500 // You can override field hashCode logic by defining methods like:
501 // int fieldNameHashCode() { ... }
502
503 int _hash = 1;
504 _hash = 31 * _hash + java.util.Objects.hashCode(mInfo);
505 _hash = 31 * _hash + java.util.Objects.hashCode(mContentProvider);
Joanne Chung332c6a92020-02-07 17:10:23 +0800506 _hash = 31 * _hash + java.util.Objects.hashCode(mInlineContentCallback);
Feng Cao04830a32019-11-13 00:45:19 -0800507 return _hash;
508 }
509
Joanne Chung332c6a92020-02-07 17:10:23 +0800510 @DataClass.Generated.Member
511 static Parcelling<InlineContentCallbackImpl> sParcellingForInlineContentCallback =
512 Parcelling.Cache.get(
513 InlineContentCallbackImplParceling.class);
514 static {
515 if (sParcellingForInlineContentCallback == null) {
516 sParcellingForInlineContentCallback = Parcelling.Cache.put(
517 new InlineContentCallbackImplParceling());
518 }
519 }
520
Feng Cao04830a32019-11-13 00:45:19 -0800521 @Override
522 @DataClass.Generated.Member
Joanne Chung332c6a92020-02-07 17:10:23 +0800523 public void writeToParcel(@NonNull Parcel dest, int flags) {
Feng Cao04830a32019-11-13 00:45:19 -0800524 // You can override field parcelling by defining methods like:
525 // void parcelFieldName(Parcel dest, int flags) { ... }
526
527 byte flg = 0;
528 if (mContentProvider != null) flg |= 0x2;
Joanne Chung332c6a92020-02-07 17:10:23 +0800529 if (mInlineContentCallback != null) flg |= 0x4;
Feng Cao04830a32019-11-13 00:45:19 -0800530 dest.writeByte(flg);
531 dest.writeTypedObject(mInfo, flags);
532 if (mContentProvider != null) dest.writeStrongInterface(mContentProvider);
Joanne Chung332c6a92020-02-07 17:10:23 +0800533 sParcellingForInlineContentCallback.parcel(mInlineContentCallback, dest, flags);
Feng Cao04830a32019-11-13 00:45:19 -0800534 }
535
536 @Override
537 @DataClass.Generated.Member
538 public int describeContents() { return 0; }
539
540 /** @hide */
541 @SuppressWarnings({"unchecked", "RedundantCast"})
542 @DataClass.Generated.Member
Joanne Chung332c6a92020-02-07 17:10:23 +0800543 /* package-private */ InlineSuggestion(@NonNull Parcel in) {
Feng Cao04830a32019-11-13 00:45:19 -0800544 // You can override field unparcelling by defining methods like:
545 // static FieldType unparcelFieldName(Parcel in) { ... }
546
547 byte flg = in.readByte();
548 InlineSuggestionInfo info = (InlineSuggestionInfo) in.readTypedObject(InlineSuggestionInfo.CREATOR);
549 IInlineContentProvider contentProvider = (flg & 0x2) == 0 ? null : IInlineContentProvider.Stub.asInterface(in.readStrongBinder());
Joanne Chung332c6a92020-02-07 17:10:23 +0800550 InlineContentCallbackImpl inlineContentCallback = sParcellingForInlineContentCallback.unparcel(in);
Feng Cao04830a32019-11-13 00:45:19 -0800551
552 this.mInfo = info;
553 com.android.internal.util.AnnotationValidations.validate(
554 NonNull.class, null, mInfo);
555 this.mContentProvider = contentProvider;
Joanne Chung332c6a92020-02-07 17:10:23 +0800556 this.mInlineContentCallback = inlineContentCallback;
Feng Cao04830a32019-11-13 00:45:19 -0800557
558 // onConstructed(); // You can define this method to get a callback
559 }
560
561 @DataClass.Generated.Member
562 public static final @NonNull Parcelable.Creator<InlineSuggestion> CREATOR
563 = new Parcelable.Creator<InlineSuggestion>() {
564 @Override
565 public InlineSuggestion[] newArray(int size) {
566 return new InlineSuggestion[size];
567 }
568
569 @Override
Joanne Chung332c6a92020-02-07 17:10:23 +0800570 public InlineSuggestion createFromParcel(@NonNull Parcel in) {
Feng Cao04830a32019-11-13 00:45:19 -0800571 return new InlineSuggestion(in);
572 }
573 };
574
575 @DataClass.Generated(
Feng Caob46851c2020-04-29 18:22:49 -0700576 time = 1588308946517L,
Feng Caodeec8f02020-03-10 18:14:13 -0700577 codegenVersion = "1.0.15",
Feng Cao04830a32019-11-13 00:45:19 -0800578 sourceFile = "frameworks/base/core/java/android/view/inputmethod/InlineSuggestion.java",
Feng Caobd26abb2020-04-24 11:35:58 -0700579 inputSignatures = "private static final java.lang.String TAG\nprivate final @android.annotation.NonNull android.view.inputmethod.InlineSuggestionInfo mInfo\nprivate final @android.annotation.Nullable com.android.internal.view.inline.IInlineContentProvider mContentProvider\nprivate @com.android.internal.util.DataClass.ParcelWith(android.view.inputmethod.InlineSuggestion.InlineContentCallbackImplParceling.class) @android.annotation.Nullable android.view.inputmethod.InlineSuggestion.InlineContentCallbackImpl mInlineContentCallback\npublic static @android.annotation.TestApi @android.annotation.NonNull android.view.inputmethod.InlineSuggestion newInlineSuggestion(android.view.inputmethod.InlineSuggestionInfo)\npublic void inflate(android.content.Context,android.util.Size,java.util.concurrent.Executor,java.util.function.Consumer<android.widget.inline.InlineContentView>)\nprivate static boolean isValid(int,int,int)\nprivate synchronized android.view.inputmethod.InlineSuggestion.InlineContentCallbackImpl getInlineContentCallback(android.content.Context,java.util.concurrent.Executor,java.util.function.Consumer<android.widget.inline.InlineContentView>)\nclass InlineSuggestion extends java.lang.Object implements [android.os.Parcelable]\n@com.android.internal.util.DataClass(genEqualsHashCode=true, genToString=true, genHiddenConstDefs=true, genHiddenConstructor=true)")
Feng Cao04830a32019-11-13 00:45:19 -0800580 @Deprecated
581 private void __metadata() {}
582
583
584 //@formatter:on
585 // End of generated code
586
587}