Loading core/api/current.txt +7 −6 Original line number Diff line number Diff line Loading @@ -48466,6 +48466,7 @@ package android.view { method public boolean checkInputConnectionProxy(android.view.View); method public void clearAnimation(); method public void clearFocus(); method public void clearViewTranslationCallback(); method public static int combineMeasuredStates(int, int); method protected int computeHorizontalScrollExtent(); method protected int computeHorizontalScrollOffset(); Loading Loading @@ -48502,7 +48503,7 @@ package android.view { method public boolean dispatchPopulateAccessibilityEvent(android.view.accessibility.AccessibilityEvent); method public void dispatchProvideAutofillStructure(@NonNull android.view.ViewStructure, int); method public void dispatchProvideStructure(android.view.ViewStructure); method public void dispatchRequestTranslation(@NonNull java.util.Map<android.view.autofill.AutofillId,long[]>, @NonNull int[], @Nullable android.view.translation.TranslationCapability, @NonNull java.util.List<android.view.translation.ViewTranslationRequest>); method public void dispatchRequestTranslation(@NonNull java.util.Map<android.view.autofill.AutofillId,long[]>, @NonNull int[], @NonNull android.view.translation.TranslationCapability, @NonNull java.util.List<android.view.translation.ViewTranslationRequest>); method protected void dispatchRestoreInstanceState(android.util.SparseArray<android.os.Parcelable>); method protected void dispatchSaveInstanceState(android.util.SparseArray<android.os.Parcelable>); method public void dispatchScrollCaptureSearch(@NonNull android.graphics.Rect, @NonNull android.graphics.Point, @NonNull java.util.function.Consumer<android.view.ScrollCaptureTarget>); Loading Loading @@ -48699,7 +48700,7 @@ package android.view { method @Nullable public android.graphics.drawable.Drawable getVerticalScrollbarTrackDrawable(); method public int getVerticalScrollbarWidth(); method @Nullable public android.view.ViewRoot getViewRoot(); method @Nullable public android.view.translation.ViewTranslationCallback getViewTranslationCallback(); method @Nullable public android.view.translation.ViewTranslationResponse getViewTranslationResponse(); method public android.view.ViewTreeObserver getViewTreeObserver(); method public int getVisibility(); method public final int getWidth(); Loading Loading @@ -48799,8 +48800,8 @@ package android.view { method protected void onCreateContextMenu(android.view.ContextMenu); method protected int[] onCreateDrawableState(int); method public android.view.inputmethod.InputConnection onCreateInputConnection(android.view.inputmethod.EditorInfo); method @Nullable public android.view.translation.ViewTranslationRequest onCreateTranslationRequest(@NonNull int[]); method public void onCreateTranslationRequests(@NonNull long[], @NonNull int[], @NonNull java.util.function.Consumer<android.view.translation.ViewTranslationRequest>); method public void onCreateViewTranslationRequest(@NonNull int[], @NonNull java.util.function.Consumer<android.view.translation.ViewTranslationRequest>); method public void onCreateVirtualViewTranslationRequests(@NonNull long[], @NonNull int[], @NonNull java.util.function.Consumer<android.view.translation.ViewTranslationRequest>); method @CallSuper protected void onDetachedFromWindow(); method protected void onDisplayHint(int); method public boolean onDragEvent(android.view.DragEvent); Loading Loading @@ -48845,8 +48846,8 @@ package android.view { method public void onStartTemporaryDetach(); method public boolean onTouchEvent(android.view.MotionEvent); method public boolean onTrackballEvent(android.view.MotionEvent); method public void onTranslationResponse(@NonNull android.view.translation.ViewTranslationResponse); method public void onTranslationResponse(@NonNull android.util.LongSparseArray<android.view.translation.ViewTranslationResponse>); method public void onViewTranslationResponse(@NonNull android.view.translation.ViewTranslationResponse); method public void onVirtualViewTranslationResponses(@NonNull android.util.LongSparseArray<android.view.translation.ViewTranslationResponse>); method @CallSuper public void onVisibilityAggregated(boolean); method protected void onVisibilityChanged(@NonNull android.view.View, int); method public void onWindowFocusChanged(boolean); core/api/system-current.txt +2 −2 Original line number Diff line number Diff line Loading @@ -14825,7 +14825,7 @@ package android.webkit { method public default boolean onCheckIsTextEditor(); method public void onConfigurationChanged(android.content.res.Configuration); method public android.view.inputmethod.InputConnection onCreateInputConnection(android.view.inputmethod.EditorInfo); method public default void onCreateTranslationRequests(@NonNull long[], @NonNull int[], @NonNull java.util.function.Consumer<android.view.translation.ViewTranslationRequest>); method public default void onCreateVirtualViewTranslationRequests(@NonNull long[], @NonNull int[], @NonNull java.util.function.Consumer<android.view.translation.ViewTranslationRequest>); method public void onDetachedFromWindow(); method public boolean onDragEvent(android.view.DragEvent); method public void onDraw(android.graphics.Canvas); Loading @@ -14850,7 +14850,7 @@ package android.webkit { method public void onStartTemporaryDetach(); method public boolean onTouchEvent(android.view.MotionEvent); method public boolean onTrackballEvent(android.view.MotionEvent); method public default void onTranslationResponse(@NonNull android.util.LongSparseArray<android.view.translation.ViewTranslationResponse>); method public default void onVirtualViewTranslationResponses(@NonNull android.util.LongSparseArray<android.view.translation.ViewTranslationResponse>); method public void onVisibilityChanged(android.view.View, int); method public void onWindowFocusChanged(boolean); method public void onWindowVisibilityChanged(int); core/java/android/view/View.java +100 −59 Original line number Diff line number Diff line Loading @@ -5260,6 +5260,10 @@ public class View implements Drawable.Callback, KeyEvent.Callback, @Nullable private ViewTranslationCallback mViewTranslationCallback; @Nullable private ViewTranslationResponse mViewTranslationResponse; /** * Simple constructor to use when creating a view from code. * Loading Loading @@ -30770,57 +30774,50 @@ public class View implements Drawable.Callback, KeyEvent.Callback, } /** * Returns a {@link ViewTranslationRequest} which represents the content to be translated. * Collects a {@link ViewTranslationRequest} which represents the content to be translated in * the view. * * <p>The default implementation does nothing and returns null.</p> * <p>The default implementation does nothing.</p> * * @param supportedFormats the supported translation formats. For now, the only possible value * is the {@link android.view.translation.TranslationSpec#DATA_FORMAT_TEXT}. * @return the {@link ViewTranslationRequest} which contains the information to be translated or * {@code null} if this View doesn't support translation. * The {@link AutofillId} must be set on the returned value. * @param requestsCollector a {@link ViewTranslationRequest} collector that can be used to * collect the information to be translated in the view. The {@code requestsCollector} only * accepts one request; an IllegalStateException is thrown if more than one * {@link ViewTranslationRequest} is submitted to it. The {@link AutofillId} must be set on the * {@link ViewTranslationRequest}. */ @Nullable public ViewTranslationRequest onCreateTranslationRequest( @NonNull @DataFormat int[] supportedFormats) { return null; public void onCreateViewTranslationRequest(@NonNull @DataFormat int[] supportedFormats, @NonNull Consumer<ViewTranslationRequest> requestsCollector) { } /** * Returns a {@link ViewTranslationRequest} list which represents the content to be translated * in the virtual view. This is called if this view returned a virtual view structure * from {@link #onProvideContentCaptureStructure} and the system determined that those virtual * views were relevant for translation. * Collects {@link ViewTranslationRequest}s which represents the content to be translated * for the virtual views in the host view. This is called if this view returned a virtual * view structure from {@link #onProvideContentCaptureStructure} and the system determined that * those virtual views were relevant for translation. * * <p>The default implementation does nothing.</p> * * @param virtualChildIds the virtual child ids which represents the child views in the virtual * @param virtualIds the virtual view ids which represents the virtual views in the host * view. * @param supportedFormats the supported translation formats. For now, the only possible value * is the {@link android.view.translation.TranslationSpec#DATA_FORMAT_TEXT}. * @param requestsCollector a {@link ViewTranslationRequest} collector that can be called * multiple times to collect the information to be translated in the virtual view. One * multiple times to collect the information to be translated in the host view. One * {@link ViewTranslationRequest} per virtual child. The {@link ViewTranslationRequest} must * contains the {@link AutofillId} corresponding to the virtualChildIds. Do not keep this * Consumer after the method returns. */ @SuppressLint("NullableCollection") public void onCreateTranslationRequests(@NonNull long[] virtualChildIds, public void onCreateVirtualViewTranslationRequests(@NonNull long[] virtualIds, @NonNull @DataFormat int[] supportedFormats, @NonNull Consumer<ViewTranslationRequest> requestsCollector) { // no-op } /** * Returns a {@link ViewTranslationCallback} that is used to display/hide the translated * information. If the View supports displaying translated content, it should implement * {@link ViewTranslationCallback}. * * <p>The default implementation returns null if developers don't set the customized * {@link ViewTranslationCallback} by {@link #setViewTranslationCallback} </p> * * @return a {@link ViewTranslationCallback} that is used to control how to display the * translated information or {@code null} if this View doesn't support translation. * @hide */ @Nullable public ViewTranslationCallback getViewTranslationCallback() { Loading @@ -30840,30 +30837,52 @@ public class View implements Drawable.Callback, KeyEvent.Callback, } /** * Called when the content from {@link View#onCreateTranslationRequest} had been translated by * the TranslationService. * Clear the {@link ViewTranslationCallback} from this view. */ public void clearViewTranslationCallback() { mViewTranslationCallback = null; } /** * Returns the {@link ViewTranslationResponse} associated with this view. The response will be * set when the translation is done then {@link #onViewTranslationResponse} is called. The * {@link ViewTranslationCallback} can use to get {@link ViewTranslationResponse} to display the * translated information. * * <p> The default implementation does nothing.</p> * @return a {@link ViewTranslationResponse} that contains the translated information associated * with this view or {@code null} if this View doesn't have the translation. */ @Nullable public ViewTranslationResponse getViewTranslationResponse() { return mViewTranslationResponse; } /** * Called when the content from {@link View#onCreateViewTranslationRequest} had been translated * by the TranslationService. * * <p> The default implementation will set the ViewTranslationResponse that can be get from * {@link View#getViewTranslationResponse}. </p> * * @param response a {@link ViewTranslationResponse} that contains the translated information * which can be shown in the view. */ public void onTranslationResponse(@NonNull ViewTranslationResponse response) { // no-op public void onViewTranslationResponse(@NonNull ViewTranslationResponse response) { mViewTranslationResponse = response; } /** * Called when the content from {@link View#onCreateTranslationRequest} had been translated by * the TranslationService. * Called when the content from {@link View#onCreateVirtualViewTranslationRequests} had been * translated by the TranslationService. * * <p> The default implementation does nothing.</p> * * @param response a {@link ViewTranslationResponse} SparseArray for the request that send by * {@link View#onCreateTranslationRequests} that contains the translated information which can * be shown in the view. The key of SparseArray is * the virtual child ids. * {@link View#onCreateVirtualViewTranslationRequests} that contains the translated information * which can be shown in the view. The key of SparseArray is the virtual child ids. */ public void onTranslationResponse(@NonNull LongSparseArray<ViewTranslationResponse> response) { public void onVirtualViewTranslationResponses( @NonNull LongSparseArray<ViewTranslationResponse> response) { // no-op } Loading @@ -30871,16 +30890,18 @@ public class View implements Drawable.Callback, KeyEvent.Callback, * Dispatch to collect the {@link ViewTranslationRequest}s for translation purpose by traversing * the hierarchy when the app requests ui translation. Typically, this method should only be * overridden by subclasses that provide a view hierarchy (such as {@link ViewGroup}). Other * classes should override {@link View#onCreateTranslationRequest}. When requested to start the * ui translation, the system will call this method to traverse the view hierarchy to call * {@link View#onCreateTranslationRequest} to build {@link ViewTranslationRequest}s and create a * classes should override {@link View#onCreateViewTranslationRequest} for normal view or * override {@link View#onVirtualViewTranslationResponses} for view contains virtual children. * When requested to start the ui translation, the system will call this method to traverse the * view hierarchy to collect {@link ViewTranslationRequest}s and create a * {@link android.view.translation.Translator} to translate the requests. All the * {@link ViewTranslationRequest}s must be added when the traversal is done. * * <p> The default implementation calls {@link View#onCreateTranslationRequest} to build * {@link ViewTranslationRequest} if the view should be translated. The view is marked as having * {@link #setHasTransientState(boolean) transient state} so that recycling of views doesn't * prevent the system from attaching the response to it.</p> * <p> The default implementation calls {@link View#onCreateViewTranslationRequest} for normal * view or calls {@link View#onVirtualViewTranslationResponses} for view contains virtual * children to build {@link ViewTranslationRequest} if the view should be translated. * The view is marked as having {@link #setHasTransientState(boolean) transient state} so that * recycling of views doesn't prevent the system from attaching the response to it.</p> * * @param viewIds a map for the view's {@link AutofillId} and its virtual child ids or * {@code null} if the view doesn't have virtual child that should be translated. The virtual Loading @@ -30893,28 +30914,48 @@ public class View implements Drawable.Callback, KeyEvent.Callback, */ public void dispatchRequestTranslation(@NonNull Map<AutofillId, long[]> viewIds, @NonNull @DataFormat int[] supportedFormats, @Nullable TranslationCapability capability, @NonNull TranslationCapability capability, @NonNull List<ViewTranslationRequest> requests) { AutofillId autofillId = getAutofillId(); if (viewIds.containsKey(autofillId)) { if (viewIds.get(autofillId) == null) { ViewTranslationRequest request = onCreateTranslationRequest(supportedFormats); if (request != null && request.getKeys().size() > 0) { // TODO: avoiding the allocation per view onCreateViewTranslationRequest(supportedFormats, new ViewTranslationRequestConsumer(requests)); } else { onCreateVirtualViewTranslationRequests(viewIds.get(autofillId), supportedFormats, request -> { requests.add(request); }); } } } private class ViewTranslationRequestConsumer implements Consumer<ViewTranslationRequest> { private final List<ViewTranslationRequest> mRequests; private boolean mCalled; ViewTranslationRequestConsumer(List<ViewTranslationRequest> requests) { mRequests = requests; } @Override public void accept(ViewTranslationRequest request) { if (mCalled) { throw new IllegalStateException("The translation Consumer is not reusable."); } mCalled = true; if (request != null && request.getKeys().size() > 0) { mRequests.add(request); if (Log.isLoggable(CONTENT_CAPTURE_LOG_TAG, Log.VERBOSE)) { Log.v(CONTENT_CAPTURE_LOG_TAG, "Calling setHasTransientState(true) for " + autofillId); + getAutofillId()); } // TODO: Add a default ViewTranslationCallback for View that resets this in // onClearTranslation(). Also update the javadoc for this method to mention // that. setHasTransientState(true); } } else { onCreateTranslationRequests(viewIds.get(autofillId), supportedFormats, request -> { requests.add(request); }); } } } core/java/android/view/translation/UiTranslationController.java +2 −3 Original line number Diff line number Diff line Loading @@ -315,7 +315,7 @@ public class UiTranslationController { } return; } view.onTranslationResponse(virtualChildResponse); view.onVirtualViewTranslationResponses(virtualChildResponse); if (view.getViewTranslationCallback() != null) { view.getViewTranslationCallback().onShowTranslation(view); } Loading Loading @@ -373,8 +373,7 @@ public class UiTranslationController { // TODO: Do this for specific views on request only. callback.enableContentPadding(); view.onTranslationResponse(response); view.onViewTranslationResponse(response); callback.onShowTranslation(view); }); } Loading core/java/android/view/translation/ViewTranslationCallback.java +10 −6 Original line number Diff line number Diff line Loading @@ -21,23 +21,27 @@ import android.annotation.UiThread; import android.view.View; /** * Callback for handling the translated information show or hide in the {@link View}. See {@link * View#onTranslationResponse} for how to get the translated information. * Callback for handling the translated information show or hide in the {@link View}. */ @UiThread public interface ViewTranslationCallback { /** * Called when the translated text is ready to show or if the user has requested to reshow the * translated content after hiding it. This may be called before the translation results are * returned through the {@link View#onTranslationResponse}. * translated content after hiding it. * <p> * The translated content can be obtained from {@link View#getViewTranslationResponse}. This * method will not be called before {@link View#onViewTranslationResponse} or * {@link View#onVirtualViewTranslationResponses}. * * See {@link View#onViewTranslationResponse} for how to get the translated information. * * @return {@code true} if the View handles showing the translation. */ boolean onShowTranslation(@NonNull View view); /** * Called when the user wants to show the original text instead of the translated text. This * may be called before the translation results are returned through the * {@link View#onTranslationResponse}. * method will not be called before {@link View#onViewTranslationResponse} or * {@link View#onViewTranslationResponse}. * * @return {@code true} if the View handles hiding the translation. */ Loading Loading
core/api/current.txt +7 −6 Original line number Diff line number Diff line Loading @@ -48466,6 +48466,7 @@ package android.view { method public boolean checkInputConnectionProxy(android.view.View); method public void clearAnimation(); method public void clearFocus(); method public void clearViewTranslationCallback(); method public static int combineMeasuredStates(int, int); method protected int computeHorizontalScrollExtent(); method protected int computeHorizontalScrollOffset(); Loading Loading @@ -48502,7 +48503,7 @@ package android.view { method public boolean dispatchPopulateAccessibilityEvent(android.view.accessibility.AccessibilityEvent); method public void dispatchProvideAutofillStructure(@NonNull android.view.ViewStructure, int); method public void dispatchProvideStructure(android.view.ViewStructure); method public void dispatchRequestTranslation(@NonNull java.util.Map<android.view.autofill.AutofillId,long[]>, @NonNull int[], @Nullable android.view.translation.TranslationCapability, @NonNull java.util.List<android.view.translation.ViewTranslationRequest>); method public void dispatchRequestTranslation(@NonNull java.util.Map<android.view.autofill.AutofillId,long[]>, @NonNull int[], @NonNull android.view.translation.TranslationCapability, @NonNull java.util.List<android.view.translation.ViewTranslationRequest>); method protected void dispatchRestoreInstanceState(android.util.SparseArray<android.os.Parcelable>); method protected void dispatchSaveInstanceState(android.util.SparseArray<android.os.Parcelable>); method public void dispatchScrollCaptureSearch(@NonNull android.graphics.Rect, @NonNull android.graphics.Point, @NonNull java.util.function.Consumer<android.view.ScrollCaptureTarget>); Loading Loading @@ -48699,7 +48700,7 @@ package android.view { method @Nullable public android.graphics.drawable.Drawable getVerticalScrollbarTrackDrawable(); method public int getVerticalScrollbarWidth(); method @Nullable public android.view.ViewRoot getViewRoot(); method @Nullable public android.view.translation.ViewTranslationCallback getViewTranslationCallback(); method @Nullable public android.view.translation.ViewTranslationResponse getViewTranslationResponse(); method public android.view.ViewTreeObserver getViewTreeObserver(); method public int getVisibility(); method public final int getWidth(); Loading Loading @@ -48799,8 +48800,8 @@ package android.view { method protected void onCreateContextMenu(android.view.ContextMenu); method protected int[] onCreateDrawableState(int); method public android.view.inputmethod.InputConnection onCreateInputConnection(android.view.inputmethod.EditorInfo); method @Nullable public android.view.translation.ViewTranslationRequest onCreateTranslationRequest(@NonNull int[]); method public void onCreateTranslationRequests(@NonNull long[], @NonNull int[], @NonNull java.util.function.Consumer<android.view.translation.ViewTranslationRequest>); method public void onCreateViewTranslationRequest(@NonNull int[], @NonNull java.util.function.Consumer<android.view.translation.ViewTranslationRequest>); method public void onCreateVirtualViewTranslationRequests(@NonNull long[], @NonNull int[], @NonNull java.util.function.Consumer<android.view.translation.ViewTranslationRequest>); method @CallSuper protected void onDetachedFromWindow(); method protected void onDisplayHint(int); method public boolean onDragEvent(android.view.DragEvent); Loading Loading @@ -48845,8 +48846,8 @@ package android.view { method public void onStartTemporaryDetach(); method public boolean onTouchEvent(android.view.MotionEvent); method public boolean onTrackballEvent(android.view.MotionEvent); method public void onTranslationResponse(@NonNull android.view.translation.ViewTranslationResponse); method public void onTranslationResponse(@NonNull android.util.LongSparseArray<android.view.translation.ViewTranslationResponse>); method public void onViewTranslationResponse(@NonNull android.view.translation.ViewTranslationResponse); method public void onVirtualViewTranslationResponses(@NonNull android.util.LongSparseArray<android.view.translation.ViewTranslationResponse>); method @CallSuper public void onVisibilityAggregated(boolean); method protected void onVisibilityChanged(@NonNull android.view.View, int); method public void onWindowFocusChanged(boolean);
core/api/system-current.txt +2 −2 Original line number Diff line number Diff line Loading @@ -14825,7 +14825,7 @@ package android.webkit { method public default boolean onCheckIsTextEditor(); method public void onConfigurationChanged(android.content.res.Configuration); method public android.view.inputmethod.InputConnection onCreateInputConnection(android.view.inputmethod.EditorInfo); method public default void onCreateTranslationRequests(@NonNull long[], @NonNull int[], @NonNull java.util.function.Consumer<android.view.translation.ViewTranslationRequest>); method public default void onCreateVirtualViewTranslationRequests(@NonNull long[], @NonNull int[], @NonNull java.util.function.Consumer<android.view.translation.ViewTranslationRequest>); method public void onDetachedFromWindow(); method public boolean onDragEvent(android.view.DragEvent); method public void onDraw(android.graphics.Canvas); Loading @@ -14850,7 +14850,7 @@ package android.webkit { method public void onStartTemporaryDetach(); method public boolean onTouchEvent(android.view.MotionEvent); method public boolean onTrackballEvent(android.view.MotionEvent); method public default void onTranslationResponse(@NonNull android.util.LongSparseArray<android.view.translation.ViewTranslationResponse>); method public default void onVirtualViewTranslationResponses(@NonNull android.util.LongSparseArray<android.view.translation.ViewTranslationResponse>); method public void onVisibilityChanged(android.view.View, int); method public void onWindowFocusChanged(boolean); method public void onWindowVisibilityChanged(int);
core/java/android/view/View.java +100 −59 Original line number Diff line number Diff line Loading @@ -5260,6 +5260,10 @@ public class View implements Drawable.Callback, KeyEvent.Callback, @Nullable private ViewTranslationCallback mViewTranslationCallback; @Nullable private ViewTranslationResponse mViewTranslationResponse; /** * Simple constructor to use when creating a view from code. * Loading Loading @@ -30770,57 +30774,50 @@ public class View implements Drawable.Callback, KeyEvent.Callback, } /** * Returns a {@link ViewTranslationRequest} which represents the content to be translated. * Collects a {@link ViewTranslationRequest} which represents the content to be translated in * the view. * * <p>The default implementation does nothing and returns null.</p> * <p>The default implementation does nothing.</p> * * @param supportedFormats the supported translation formats. For now, the only possible value * is the {@link android.view.translation.TranslationSpec#DATA_FORMAT_TEXT}. * @return the {@link ViewTranslationRequest} which contains the information to be translated or * {@code null} if this View doesn't support translation. * The {@link AutofillId} must be set on the returned value. * @param requestsCollector a {@link ViewTranslationRequest} collector that can be used to * collect the information to be translated in the view. The {@code requestsCollector} only * accepts one request; an IllegalStateException is thrown if more than one * {@link ViewTranslationRequest} is submitted to it. The {@link AutofillId} must be set on the * {@link ViewTranslationRequest}. */ @Nullable public ViewTranslationRequest onCreateTranslationRequest( @NonNull @DataFormat int[] supportedFormats) { return null; public void onCreateViewTranslationRequest(@NonNull @DataFormat int[] supportedFormats, @NonNull Consumer<ViewTranslationRequest> requestsCollector) { } /** * Returns a {@link ViewTranslationRequest} list which represents the content to be translated * in the virtual view. This is called if this view returned a virtual view structure * from {@link #onProvideContentCaptureStructure} and the system determined that those virtual * views were relevant for translation. * Collects {@link ViewTranslationRequest}s which represents the content to be translated * for the virtual views in the host view. This is called if this view returned a virtual * view structure from {@link #onProvideContentCaptureStructure} and the system determined that * those virtual views were relevant for translation. * * <p>The default implementation does nothing.</p> * * @param virtualChildIds the virtual child ids which represents the child views in the virtual * @param virtualIds the virtual view ids which represents the virtual views in the host * view. * @param supportedFormats the supported translation formats. For now, the only possible value * is the {@link android.view.translation.TranslationSpec#DATA_FORMAT_TEXT}. * @param requestsCollector a {@link ViewTranslationRequest} collector that can be called * multiple times to collect the information to be translated in the virtual view. One * multiple times to collect the information to be translated in the host view. One * {@link ViewTranslationRequest} per virtual child. The {@link ViewTranslationRequest} must * contains the {@link AutofillId} corresponding to the virtualChildIds. Do not keep this * Consumer after the method returns. */ @SuppressLint("NullableCollection") public void onCreateTranslationRequests(@NonNull long[] virtualChildIds, public void onCreateVirtualViewTranslationRequests(@NonNull long[] virtualIds, @NonNull @DataFormat int[] supportedFormats, @NonNull Consumer<ViewTranslationRequest> requestsCollector) { // no-op } /** * Returns a {@link ViewTranslationCallback} that is used to display/hide the translated * information. If the View supports displaying translated content, it should implement * {@link ViewTranslationCallback}. * * <p>The default implementation returns null if developers don't set the customized * {@link ViewTranslationCallback} by {@link #setViewTranslationCallback} </p> * * @return a {@link ViewTranslationCallback} that is used to control how to display the * translated information or {@code null} if this View doesn't support translation. * @hide */ @Nullable public ViewTranslationCallback getViewTranslationCallback() { Loading @@ -30840,30 +30837,52 @@ public class View implements Drawable.Callback, KeyEvent.Callback, } /** * Called when the content from {@link View#onCreateTranslationRequest} had been translated by * the TranslationService. * Clear the {@link ViewTranslationCallback} from this view. */ public void clearViewTranslationCallback() { mViewTranslationCallback = null; } /** * Returns the {@link ViewTranslationResponse} associated with this view. The response will be * set when the translation is done then {@link #onViewTranslationResponse} is called. The * {@link ViewTranslationCallback} can use to get {@link ViewTranslationResponse} to display the * translated information. * * <p> The default implementation does nothing.</p> * @return a {@link ViewTranslationResponse} that contains the translated information associated * with this view or {@code null} if this View doesn't have the translation. */ @Nullable public ViewTranslationResponse getViewTranslationResponse() { return mViewTranslationResponse; } /** * Called when the content from {@link View#onCreateViewTranslationRequest} had been translated * by the TranslationService. * * <p> The default implementation will set the ViewTranslationResponse that can be get from * {@link View#getViewTranslationResponse}. </p> * * @param response a {@link ViewTranslationResponse} that contains the translated information * which can be shown in the view. */ public void onTranslationResponse(@NonNull ViewTranslationResponse response) { // no-op public void onViewTranslationResponse(@NonNull ViewTranslationResponse response) { mViewTranslationResponse = response; } /** * Called when the content from {@link View#onCreateTranslationRequest} had been translated by * the TranslationService. * Called when the content from {@link View#onCreateVirtualViewTranslationRequests} had been * translated by the TranslationService. * * <p> The default implementation does nothing.</p> * * @param response a {@link ViewTranslationResponse} SparseArray for the request that send by * {@link View#onCreateTranslationRequests} that contains the translated information which can * be shown in the view. The key of SparseArray is * the virtual child ids. * {@link View#onCreateVirtualViewTranslationRequests} that contains the translated information * which can be shown in the view. The key of SparseArray is the virtual child ids. */ public void onTranslationResponse(@NonNull LongSparseArray<ViewTranslationResponse> response) { public void onVirtualViewTranslationResponses( @NonNull LongSparseArray<ViewTranslationResponse> response) { // no-op } Loading @@ -30871,16 +30890,18 @@ public class View implements Drawable.Callback, KeyEvent.Callback, * Dispatch to collect the {@link ViewTranslationRequest}s for translation purpose by traversing * the hierarchy when the app requests ui translation. Typically, this method should only be * overridden by subclasses that provide a view hierarchy (such as {@link ViewGroup}). Other * classes should override {@link View#onCreateTranslationRequest}. When requested to start the * ui translation, the system will call this method to traverse the view hierarchy to call * {@link View#onCreateTranslationRequest} to build {@link ViewTranslationRequest}s and create a * classes should override {@link View#onCreateViewTranslationRequest} for normal view or * override {@link View#onVirtualViewTranslationResponses} for view contains virtual children. * When requested to start the ui translation, the system will call this method to traverse the * view hierarchy to collect {@link ViewTranslationRequest}s and create a * {@link android.view.translation.Translator} to translate the requests. All the * {@link ViewTranslationRequest}s must be added when the traversal is done. * * <p> The default implementation calls {@link View#onCreateTranslationRequest} to build * {@link ViewTranslationRequest} if the view should be translated. The view is marked as having * {@link #setHasTransientState(boolean) transient state} so that recycling of views doesn't * prevent the system from attaching the response to it.</p> * <p> The default implementation calls {@link View#onCreateViewTranslationRequest} for normal * view or calls {@link View#onVirtualViewTranslationResponses} for view contains virtual * children to build {@link ViewTranslationRequest} if the view should be translated. * The view is marked as having {@link #setHasTransientState(boolean) transient state} so that * recycling of views doesn't prevent the system from attaching the response to it.</p> * * @param viewIds a map for the view's {@link AutofillId} and its virtual child ids or * {@code null} if the view doesn't have virtual child that should be translated. The virtual Loading @@ -30893,28 +30914,48 @@ public class View implements Drawable.Callback, KeyEvent.Callback, */ public void dispatchRequestTranslation(@NonNull Map<AutofillId, long[]> viewIds, @NonNull @DataFormat int[] supportedFormats, @Nullable TranslationCapability capability, @NonNull TranslationCapability capability, @NonNull List<ViewTranslationRequest> requests) { AutofillId autofillId = getAutofillId(); if (viewIds.containsKey(autofillId)) { if (viewIds.get(autofillId) == null) { ViewTranslationRequest request = onCreateTranslationRequest(supportedFormats); if (request != null && request.getKeys().size() > 0) { // TODO: avoiding the allocation per view onCreateViewTranslationRequest(supportedFormats, new ViewTranslationRequestConsumer(requests)); } else { onCreateVirtualViewTranslationRequests(viewIds.get(autofillId), supportedFormats, request -> { requests.add(request); }); } } } private class ViewTranslationRequestConsumer implements Consumer<ViewTranslationRequest> { private final List<ViewTranslationRequest> mRequests; private boolean mCalled; ViewTranslationRequestConsumer(List<ViewTranslationRequest> requests) { mRequests = requests; } @Override public void accept(ViewTranslationRequest request) { if (mCalled) { throw new IllegalStateException("The translation Consumer is not reusable."); } mCalled = true; if (request != null && request.getKeys().size() > 0) { mRequests.add(request); if (Log.isLoggable(CONTENT_CAPTURE_LOG_TAG, Log.VERBOSE)) { Log.v(CONTENT_CAPTURE_LOG_TAG, "Calling setHasTransientState(true) for " + autofillId); + getAutofillId()); } // TODO: Add a default ViewTranslationCallback for View that resets this in // onClearTranslation(). Also update the javadoc for this method to mention // that. setHasTransientState(true); } } else { onCreateTranslationRequests(viewIds.get(autofillId), supportedFormats, request -> { requests.add(request); }); } } }
core/java/android/view/translation/UiTranslationController.java +2 −3 Original line number Diff line number Diff line Loading @@ -315,7 +315,7 @@ public class UiTranslationController { } return; } view.onTranslationResponse(virtualChildResponse); view.onVirtualViewTranslationResponses(virtualChildResponse); if (view.getViewTranslationCallback() != null) { view.getViewTranslationCallback().onShowTranslation(view); } Loading Loading @@ -373,8 +373,7 @@ public class UiTranslationController { // TODO: Do this for specific views on request only. callback.enableContentPadding(); view.onTranslationResponse(response); view.onViewTranslationResponse(response); callback.onShowTranslation(view); }); } Loading
core/java/android/view/translation/ViewTranslationCallback.java +10 −6 Original line number Diff line number Diff line Loading @@ -21,23 +21,27 @@ import android.annotation.UiThread; import android.view.View; /** * Callback for handling the translated information show or hide in the {@link View}. See {@link * View#onTranslationResponse} for how to get the translated information. * Callback for handling the translated information show or hide in the {@link View}. */ @UiThread public interface ViewTranslationCallback { /** * Called when the translated text is ready to show or if the user has requested to reshow the * translated content after hiding it. This may be called before the translation results are * returned through the {@link View#onTranslationResponse}. * translated content after hiding it. * <p> * The translated content can be obtained from {@link View#getViewTranslationResponse}. This * method will not be called before {@link View#onViewTranslationResponse} or * {@link View#onVirtualViewTranslationResponses}. * * See {@link View#onViewTranslationResponse} for how to get the translated information. * * @return {@code true} if the View handles showing the translation. */ boolean onShowTranslation(@NonNull View view); /** * Called when the user wants to show the original text instead of the translated text. This * may be called before the translation results are returned through the * {@link View#onTranslationResponse}. * method will not be called before {@link View#onViewTranslationResponse} or * {@link View#onViewTranslationResponse}. * * @return {@code true} if the View handles hiding the translation. */ Loading