Merge "Add debug logs to help clarify the issue" into sc-dev
This commit is contained in:
@@ -25,6 +25,7 @@ import android.annotation.NonNull;
|
||||
import android.annotation.WorkerThread;
|
||||
import android.app.Activity;
|
||||
import android.content.Context;
|
||||
import android.os.Build;
|
||||
import android.os.Handler;
|
||||
import android.os.HandlerThread;
|
||||
import android.os.Process;
|
||||
@@ -54,6 +55,11 @@ import java.util.function.Consumer;
|
||||
*/
|
||||
public class UiTranslationController {
|
||||
|
||||
// TODO(b/182433547): remove Build.IS_DEBUGGABLE before ship. Enable the logging in debug build
|
||||
// to help the debug during the development phase
|
||||
public static final boolean DEBUG = Log.isLoggable(UiTranslationManager.LOG_TAG, Log.DEBUG)
|
||||
|| Build.IS_DEBUGGABLE;
|
||||
|
||||
private static final String TAG = "UiTranslationController";
|
||||
@NonNull
|
||||
private final Activity mActivity;
|
||||
@@ -93,6 +99,8 @@ public class UiTranslationController {
|
||||
if (!mActivity.isResumed()) {
|
||||
return;
|
||||
}
|
||||
Log.i(TAG, "updateUiTranslationState state: " + stateToString(state)
|
||||
+ (DEBUG ? ", views: " + views : ""));
|
||||
switch (state) {
|
||||
case STATE_UI_TRANSLATION_STARTED:
|
||||
final Pair<TranslationSpec, TranslationSpec> specs =
|
||||
@@ -149,8 +157,69 @@ public class UiTranslationController {
|
||||
translator.dump(outerPrefix, pw);
|
||||
pw.println();
|
||||
}
|
||||
synchronized (mLock) {
|
||||
final int viewSize = mViews.size();
|
||||
pw.print(outerPrefix); pw.print("number views: "); pw.println(viewSize);
|
||||
for (int i = 0; i < viewSize; i++) {
|
||||
pw.print(outerPrefix); pw.print("#"); pw.println(i);
|
||||
final AutofillId autofillId = mViews.keyAt(i);
|
||||
final View view = mViews.valueAt(i).get();
|
||||
pw.print(pfx); pw.print("autofillId: "); pw.println(autofillId);
|
||||
pw.print(pfx); pw.print("view:"); pw.println(view);
|
||||
}
|
||||
}
|
||||
// TODO(b/182433547): we will remove debug rom condition before S release then we change
|
||||
// change this back to "DEBUG"
|
||||
if (Log.isLoggable(UiTranslationManager.LOG_TAG, Log.DEBUG)) {
|
||||
dumpViewByTraversal(outerPrefix, pw);
|
||||
}
|
||||
}
|
||||
|
||||
private void dumpViewByTraversal(String outerPrefix, PrintWriter pw) {
|
||||
final ArrayList<ViewRootImpl> roots =
|
||||
WindowManagerGlobal.getInstance().getRootViews(mActivity.getActivityToken());
|
||||
pw.print(outerPrefix); pw.println("Dump views:");
|
||||
for (int rootNum = 0; rootNum < roots.size(); rootNum++) {
|
||||
final View rootView = roots.get(rootNum).getView();
|
||||
if (rootView instanceof ViewGroup) {
|
||||
dumpChildren((ViewGroup) rootView, outerPrefix, pw);
|
||||
} else {
|
||||
dumpViewInfo(rootView, outerPrefix, pw);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void dumpChildren(ViewGroup viewGroup, String outerPrefix, PrintWriter pw) {
|
||||
final int childCount = viewGroup.getChildCount();
|
||||
for (int i = 0; i < childCount; ++i) {
|
||||
final View child = viewGroup.getChildAt(i);
|
||||
if (child instanceof ViewGroup) {
|
||||
pw.print(outerPrefix); pw.println("Children: ");
|
||||
pw.print(outerPrefix); pw.print(outerPrefix); pw.println(child);
|
||||
dumpChildren((ViewGroup) child, outerPrefix, pw);
|
||||
} else {
|
||||
pw.print(outerPrefix); pw.println("End Children: ");
|
||||
pw.print(outerPrefix); pw.print(outerPrefix); pw.print(child);
|
||||
dumpViewInfo(child, outerPrefix, pw);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void dumpViewInfo(View view, String outerPrefix, PrintWriter pw) {
|
||||
final AutofillId autofillId = view.getAutofillId();
|
||||
pw.print(outerPrefix); pw.print("autofillId: "); pw.print(autofillId);
|
||||
// TODO: print TranslationTransformation
|
||||
boolean isContainsView = false;
|
||||
synchronized (mLock) {
|
||||
final WeakReference<View> viewRef = mViews.get(autofillId);
|
||||
if (viewRef != null && viewRef.get() != null) {
|
||||
isContainsView = true;
|
||||
}
|
||||
}
|
||||
pw.print(outerPrefix); pw.print("isContainsView: "); pw.println(isContainsView);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* The method is used by {@link Translator}, it will be called when the translation is done. The
|
||||
* translation result can be get from here.
|
||||
@@ -171,6 +240,9 @@ public class UiTranslationController {
|
||||
return;
|
||||
}
|
||||
final int resultCount = translatedResult.size();
|
||||
if (DEBUG) {
|
||||
Log.v(TAG, "onTranslationCompleted: receive " + resultCount + " responses.");
|
||||
}
|
||||
synchronized (mLock) {
|
||||
for (int i = 0; i < resultCount; i++) {
|
||||
final ViewTranslationResponse response = translatedResult.get(i);
|
||||
@@ -180,7 +252,7 @@ public class UiTranslationController {
|
||||
}
|
||||
final View view = mViews.get(autofillId).get();
|
||||
if (view == null) {
|
||||
Log.w(TAG, "onTranslationCompleted: the Veiew for autofill id " + autofillId
|
||||
Log.w(TAG, "onTranslationCompleted: the view for autofill id " + autofillId
|
||||
+ " may be gone.");
|
||||
continue;
|
||||
}
|
||||
@@ -208,6 +280,10 @@ public class UiTranslationController {
|
||||
@WorkerThread
|
||||
private void sendTranslationRequest(Translator translator,
|
||||
List<ViewTranslationRequest> requests) {
|
||||
if (requests.size() == 0) {
|
||||
Log.wtf(TAG, "No ViewTranslationRequest was collected.");
|
||||
return;
|
||||
}
|
||||
final TranslationRequest request = new TranslationRequest.Builder()
|
||||
.setViewTranslationRequests(requests)
|
||||
.build();
|
||||
@@ -233,7 +309,8 @@ public class UiTranslationController {
|
||||
requests.add(request);
|
||||
}
|
||||
if (currentCount == (foundViews.size() - 1)) {
|
||||
Log.v(TAG, "onUiTranslationStarted: send " + requests.size() + " request.");
|
||||
Log.v(TAG, "onUiTranslationStarted: collect " + requests.size()
|
||||
+ " requests.");
|
||||
mWorkerHandler.sendMessage(PooledLambda.obtainMessage(
|
||||
UiTranslationController::sendTranslationRequest,
|
||||
UiTranslationController.this, translator, requests));
|
||||
@@ -287,6 +364,9 @@ public class UiTranslationController {
|
||||
for (int i = 0; i < viewCounts; i++) {
|
||||
final View view = views.valueAt(i).get();
|
||||
if (view == null) {
|
||||
if (DEBUG) {
|
||||
Log.d(TAG, "View was gone for autofillid = " + views.keyAt(i));
|
||||
}
|
||||
continue;
|
||||
}
|
||||
action.accept(view);
|
||||
|
||||
@@ -42,6 +42,14 @@ public final class UiTranslationManager {
|
||||
|
||||
private static final String TAG = "UiTranslationManager";
|
||||
|
||||
/**
|
||||
* The tag which uses for enabling debug log dump. To enable it, we can use command "adb shell
|
||||
* setprop log.tag.UiTranslation DEBUG".
|
||||
*
|
||||
* @hide
|
||||
*/
|
||||
public static final String LOG_TAG = "UiTranslation";
|
||||
|
||||
/**
|
||||
* The state caller request to disable utranslation,, it is no longer need to ui translation.
|
||||
*
|
||||
|
||||
@@ -195,6 +195,7 @@ import android.view.textclassifier.TextLinks;
|
||||
import android.view.textservice.SpellCheckerSubtype;
|
||||
import android.view.textservice.TextServicesManager;
|
||||
import android.view.translation.TranslationRequestValue;
|
||||
import android.view.translation.UiTranslationController;
|
||||
import android.view.translation.ViewTranslationRequest;
|
||||
import android.view.translation.ViewTranslationResponse;
|
||||
import android.widget.RemoteViews.RemoteView;
|
||||
@@ -13835,6 +13836,10 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
|
||||
@Override
|
||||
public ViewTranslationRequest onCreateTranslationRequest() {
|
||||
if (mText == null || mText.length() == 0) {
|
||||
// TODO(b/182433547): remove before S release
|
||||
if (UiTranslationController.DEBUG) {
|
||||
Log.w(LOG_TAG, "Cannot create translation request for the empty text.");
|
||||
}
|
||||
return null;
|
||||
}
|
||||
// Not translate password, editable text and not important for translation
|
||||
@@ -13842,6 +13847,11 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
|
||||
// text selection apis, not support in S.
|
||||
boolean isPassword = isAnyPasswordInputType() || hasPasswordTransformationMethod();
|
||||
if (isTextEditable() || isPassword || isTextSelectable()) {
|
||||
// TODO(b/182433547): remove before S release
|
||||
if (UiTranslationController.DEBUG) {
|
||||
Log.w(LOG_TAG, "Cannot create translation request. editable = " + isTextEditable()
|
||||
+ ", isPassword = " + isPassword + ", selectable = " + isTextSelectable());
|
||||
}
|
||||
return null;
|
||||
}
|
||||
// TODO(b/176488462): apply the view's important for translation property
|
||||
@@ -13870,6 +13880,9 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
|
||||
// Restore to original text content.
|
||||
if (mTranslationTransformation != null) {
|
||||
setTransformationMethod(mTranslationTransformation.getOriginalTransformationMethod());
|
||||
} else {
|
||||
// TODO(b/182433547): remove before S release
|
||||
Log.w(LOG_TAG, "onPauseUiTranslation(): no translated text.");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -13889,7 +13902,8 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
|
||||
if (mTranslationTransformation != null) {
|
||||
setTransformationMethod(mTranslationTransformation);
|
||||
} else {
|
||||
Log.w(LOG_TAG, "onResumeTranslatedText(): no translated text.");
|
||||
// TODO(b/182433547): remove before S release
|
||||
Log.w(LOG_TAG, "onRestoreUiTranslation(): no translated text.");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -13910,6 +13924,9 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
|
||||
if (mTranslationTransformation != null) {
|
||||
setTransformationMethod(mTranslationTransformation.getOriginalTransformationMethod());
|
||||
mTranslationTransformation = null;
|
||||
} else {
|
||||
// TODO(b/182433547): remove before S release
|
||||
Log.w(LOG_TAG, "onFinishUiTranslation(): no translated text.");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user