From 94b6e6515c65f4d714776a1b295e29dfbbc2552f Mon Sep 17 00:00:00 2001 From: Joanne Chung Date: Tue, 1 Jun 2021 17:34:00 +0800 Subject: [PATCH] Dump the last Activity information when dumpsys translation When bugreport dumps Activity information, it will dump translation related information. But it adds -v parameter, the bugreport will only dump visible task's top Activity. If message apps go to the background, we cannot find our expected information. We try to let translation dumpsys to dump the last Activity information if the Activity isn't destroyed yet, e.g. go to background. Bug: 187889345 Test: open chat app and back home then dumpsys translation. Let Activity destroyed and make sure no Activity dump. Change-Id: Ie5b935696a74ca3f298c5e6e5994fa659389e198 --- .../translation/UiTranslationController.java | 26 ++++++++++++++-- .../TranslationManagerService.java | 5 +++ .../TranslationManagerServiceImpl.java | 31 +++++++++++++++++++ 3 files changed, 60 insertions(+), 2 deletions(-) diff --git a/core/java/android/view/translation/UiTranslationController.java b/core/java/android/view/translation/UiTranslationController.java index bf2af518969b0..790b93a1f4951 100644 --- a/core/java/android/view/translation/UiTranslationController.java +++ b/core/java/android/view/translation/UiTranslationController.java @@ -90,6 +90,8 @@ public class UiTranslationController { @NonNull private final Handler mWorkerHandler; private int mCurrentState; + @NonNull + private ArraySet mLastRequestAutofillIds; public UiTranslationController(Activity activity, Context context) { mActivity = activity; @@ -120,6 +122,9 @@ public class UiTranslationController { + (DEBUG ? (", views: " + views + ", spec: " + uiTranslationSpec) : "")); synchronized (mLock) { mCurrentState = state; + if (views != null) { + setLastRequestAutofillIdsLocked(views); + } } switch (state) { case STATE_UI_TRANSLATION_STARTED: @@ -175,13 +180,25 @@ public class UiTranslationController { } } + private void setLastRequestAutofillIdsLocked(List views) { + if (mLastRequestAutofillIds == null) { + mLastRequestAutofillIds = new ArraySet<>(); + } + if (mLastRequestAutofillIds.size() > 0) { + mLastRequestAutofillIds.clear(); + } + mLastRequestAutofillIds.addAll(views); + } + /** * Called to dump the translation information for Activity. */ public void dump(String outerPrefix, PrintWriter pw) { pw.print(outerPrefix); pw.println("UiTranslationController:"); final String pfx = outerPrefix + " "; - pw.print(pfx); pw.print("activity: "); pw.println(mActivity); + pw.print(pfx); pw.print("activity: "); pw.print(mActivity); + pw.print(pfx); pw.print("resumed: "); pw.println(mActivity.isResumed()); + pw.print(pfx); pw.print("current state: "); pw.println(mCurrentState); final int translatorSize = mTranslators.size(); pw.print(outerPrefix); pw.print("number translator: "); pw.println(translatorSize); for (int i = 0; i < translatorSize; i++) { @@ -244,13 +261,18 @@ public class UiTranslationController { pw.print(outerPrefix); pw.print("autofillId: "); pw.print(autofillId); // TODO: print TranslationTransformation boolean isContainsView = false; + boolean isRequestedView = false; synchronized (mLock) { + if (mLastRequestAutofillIds.contains(autofillId)) { + isRequestedView = true; + } final WeakReference viewRef = mViews.get(autofillId); if (viewRef != null && viewRef.get() != null) { isContainsView = true; } } - pw.print(outerPrefix); pw.print("isContainsView: "); pw.println(isContainsView); + pw.print(outerPrefix); pw.print("isContainsView: "); pw.print(isContainsView); + pw.print(outerPrefix); pw.print("isRequestedView: "); pw.println(isRequestedView); } /** diff --git a/services/translation/java/com/android/server/translation/TranslationManagerService.java b/services/translation/java/com/android/server/translation/TranslationManagerService.java index 415f055829601..41ee6b5d2ea0e 100644 --- a/services/translation/java/com/android/server/translation/TranslationManagerService.java +++ b/services/translation/java/com/android/server/translation/TranslationManagerService.java @@ -294,6 +294,11 @@ public final class TranslationManagerService synchronized (mLock) { dumpLocked("", pw); + final int userId = UserHandle.getCallingUserId(); + final TranslationManagerServiceImpl service = getServiceForUserLocked(userId); + if (service != null) { + service.dumpLocked(" ", fd, pw); + } } } diff --git a/services/translation/java/com/android/server/translation/TranslationManagerServiceImpl.java b/services/translation/java/com/android/server/translation/TranslationManagerServiceImpl.java index 2b01cdfdc27ff..16a2d8d88e39e 100644 --- a/services/translation/java/com/android/server/translation/TranslationManagerServiceImpl.java +++ b/services/translation/java/com/android/server/translation/TranslationManagerServiceImpl.java @@ -45,12 +45,17 @@ import android.view.translation.UiTranslationSpec; import com.android.internal.annotations.GuardedBy; import com.android.internal.os.IResultReceiver; +import com.android.internal.os.TransferPipe; import com.android.server.LocalServices; import com.android.server.infra.AbstractPerUserSystemService; import com.android.server.inputmethod.InputMethodManagerInternal; import com.android.server.wm.ActivityTaskManagerInternal; import com.android.server.wm.ActivityTaskManagerInternal.ActivityTokens; +import java.io.FileDescriptor; +import java.io.IOException; +import java.io.PrintWriter; +import java.lang.ref.WeakReference; import java.util.List; final class TranslationManagerServiceImpl extends @@ -69,6 +74,9 @@ final class TranslationManagerServiceImpl extends @GuardedBy("mLock") private TranslationServiceInfo mTranslationServiceInfo; + @GuardedBy("mLock") + private WeakReference mLastActivityTokens; + private ActivityTaskManagerInternal mActivityTaskManagerInternal; private final TranslationServiceRemoteCallback mRemoteServiceCallback = @@ -178,12 +186,35 @@ final class TranslationManagerServiceImpl extends taskTopActivityTokens.getApplicationThread().updateUiTranslationState( taskTopActivityTokens.getActivityToken(), state, sourceSpec, targetSpec, viewIds, uiTranslationSpec); + mLastActivityTokens = new WeakReference<>(taskTopActivityTokens); } catch (RemoteException e) { Slog.w(TAG, "Update UiTranslationState fail: " + e); } invokeCallbacks(state, sourceSpec, targetSpec); } + @GuardedBy("mLock") + public void dumpLocked(String prefix, FileDescriptor fd, PrintWriter pw) { + if (mLastActivityTokens != null) { + ActivityTokens activityTokens = mLastActivityTokens.get(); + if (activityTokens == null) { + return; + } + try (TransferPipe tp = new TransferPipe()) { + activityTokens.getApplicationThread().dumpActivity(tp.getWriteFd(), + activityTokens.getActivityToken(), prefix, + new String[]{"--translation"}); + tp.go(fd); + } catch (IOException e) { + pw.println(prefix + "Failure while dumping the activity: " + e); + } catch (RemoteException e) { + pw.println(prefix + "Got a RemoteException while dumping the activity"); + } + } else { + pw.print(prefix); pw.println("No requested UiTranslation Activity."); + } + } + private void invokeCallbacks( int state, TranslationSpec sourceSpec, TranslationSpec targetSpec) { Bundle res = new Bundle();