Merge "Optimization: find views in single traversal." into sc-dev

This commit is contained in:
Joanne Chung
2021-03-02 01:36:02 +00:00
committed by Android (Google) Code Review

View File

@@ -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);