diff options
| -rw-r--r-- | core/java/android/view/translation/UiTranslationController.java | 56 |
1 files changed, 45 insertions, 11 deletions
diff --git a/core/java/android/view/translation/UiTranslationController.java b/core/java/android/view/translation/UiTranslationController.java index b49d3c004f44..b1e45bbcd875 100644 --- a/core/java/android/view/translation/UiTranslationController.java +++ b/core/java/android/view/translation/UiTranslationController.java @@ -32,6 +32,9 @@ import android.util.ArrayMap; import android.util.Log; import android.util.Pair; import android.view.View; +import android.view.ViewGroup; +import android.view.ViewRootImpl; +import android.view.WindowManagerGlobal; import android.view.autofill.AutofillId; import android.view.translation.UiTranslationManager.UiTranslationState; @@ -194,24 +197,19 @@ public class UiTranslationController { private void onUiTranslationStarted(Translator translator, List<AutofillId> views) { synchronized (mLock) { // Find Views collect the translation data - // TODO(b/178084101): try to optimize, e.g. to this in a single traversal - final int viewCounts = views.size(); final ArrayList<TranslationRequest> requests = new ArrayList<>(); - for (int i = 0; i < viewCounts; i++) { - final AutofillId viewAutofillId = views.get(i); - final View view = mActivity.findViewByAutofillIdTraversal(viewAutofillId); - if (view == null) { - Log.w(TAG, "Can not find the View for autofill id= " + viewAutofillId); - continue; - } - mViews.put(viewAutofillId, new WeakReference<>(view)); + final ArrayList<View> foundViews = new ArrayList<>(); + findViewsTraversalByAutofillIds(views, foundViews); + for (int i = 0; i < foundViews.size(); i++) { + final View view = foundViews.get(i); + final int currentCount = i; mActivity.runOnUiThread(() -> { final TranslationRequest translationRequest = view.onCreateTranslationRequest(); if (translationRequest != null && translationRequest.getTranslationText().length() > 0) { requests.add(translationRequest); } - if (requests.size() == viewCounts) { + if (currentCount == (foundViews.size() - 1)) { Log.v(TAG, "onUiTranslationStarted: send " + requests.size() + " request."); mWorkerHandler.sendMessage(PooledLambda.obtainMessage( UiTranslationController::sendTranslationRequest, @@ -222,6 +220,42 @@ public class UiTranslationController { } } + private void findViewsTraversalByAutofillIds(List<AutofillId> sourceViewIds, + ArrayList<View> foundViews) { + final ArrayList<ViewRootImpl> roots = + WindowManagerGlobal.getInstance().getRootViews(mActivity.getActivityToken()); + for (int rootNum = 0; rootNum < roots.size(); rootNum++) { + final View rootView = roots.get(rootNum).getView(); + if (rootView instanceof ViewGroup) { + findViewsTraversalByAutofillIds((ViewGroup) rootView, sourceViewIds, foundViews); + } else { + addViewIfNeeded(sourceViewIds, rootView, foundViews); + } + } + } + + private void findViewsTraversalByAutofillIds(ViewGroup viewGroup, + List<AutofillId> sourceViewIds, ArrayList<View> foundViews) { + final int childCount = viewGroup.getChildCount(); + for (int i = 0; i < childCount; ++i) { + final View child = viewGroup.getChildAt(i); + if (child instanceof ViewGroup) { + findViewsTraversalByAutofillIds((ViewGroup) child, sourceViewIds, foundViews); + } else { + addViewIfNeeded(sourceViewIds, child, foundViews); + } + } + } + + private void addViewIfNeeded(List<AutofillId> sourceViewIds, View view, + ArrayList<View> foundViews) { + final AutofillId autofillId = view.getAutofillId(); + if (sourceViewIds.contains(autofillId)) { + mViews.put(autofillId, new WeakReference<>(view)); + foundViews.add(view); + } + } + private void runForEachView(Consumer<View> action) { synchronized (mLock) { final ArrayMap<AutofillId, WeakReference<View>> views = new ArrayMap<>(mViews); |