Pipe UiTranslationSpec through to the UiTranslationController.
And use it to conditionally enable content padding for requested views.
Fix: 179693024
Test: atest android.translation.cts.UiTranslationManagerTest
Test: adb shell dumpsys activity <ACTIVITY> --translation
Change-Id: I23fb29a60525d736f2dcf9d11b548c62332c412c
diff --git a/core/java/android/app/Activity.java b/core/java/android/app/Activity.java
index 198fa65..295943d 100644
--- a/core/java/android/app/Activity.java
+++ b/core/java/android/app/Activity.java
@@ -136,6 +136,7 @@
import android.view.contentcapture.ContentCaptureManager.ContentCaptureClient;
import android.view.translation.TranslationSpec;
import android.view.translation.UiTranslationController;
+import android.view.translation.UiTranslationSpec;
import android.widget.AdapterView;
import android.widget.Toast;
import android.widget.Toolbar;
@@ -8815,11 +8816,13 @@
* @hide
*/
public void updateUiTranslationState(int state, TranslationSpec sourceSpec,
- TranslationSpec targetSpec, List<AutofillId> viewIds) {
+ TranslationSpec targetSpec, List<AutofillId> viewIds,
+ UiTranslationSpec uiTranslationSpec) {
if (mUiTranslationController == null) {
mUiTranslationController = new UiTranslationController(this, getApplicationContext());
}
- mUiTranslationController.updateUiTranslationState(state, sourceSpec, targetSpec, viewIds);
+ mUiTranslationController.updateUiTranslationState(
+ state, sourceSpec, targetSpec, viewIds, uiTranslationSpec);
}
class HostCallbacks extends FragmentHostCallback<Activity> {
diff --git a/core/java/android/app/ActivityThread.java b/core/java/android/app/ActivityThread.java
index ff210e1..3713b7c 100644
--- a/core/java/android/app/ActivityThread.java
+++ b/core/java/android/app/ActivityThread.java
@@ -178,6 +178,7 @@
import android.view.contentcapture.IContentCaptureManager;
import android.view.contentcapture.IContentCaptureOptionsCallback;
import android.view.translation.TranslationSpec;
+import android.view.translation.UiTranslationSpec;
import android.webkit.WebView;
import android.window.SizeConfigurationBuckets;
import android.window.SplashScreen;
@@ -1843,13 +1844,15 @@
@Override
public void updateUiTranslationState(IBinder activityToken, int state,
- TranslationSpec sourceSpec, TranslationSpec targetSpec, List<AutofillId> viewIds) {
+ TranslationSpec sourceSpec, TranslationSpec targetSpec, List<AutofillId> viewIds,
+ UiTranslationSpec uiTranslationSpec) {
SomeArgs args = SomeArgs.obtain();
args.arg1 = activityToken;
args.arg2 = state;
args.arg3 = sourceSpec;
args.arg4 = targetSpec;
args.arg5 = viewIds;
+ args.arg6 = uiTranslationSpec;
sendMessage(H.UPDATE_UI_TRANSLATION_STATE, args);
}
}
@@ -2212,7 +2215,7 @@
final SomeArgs args = (SomeArgs) msg.obj;
updateUiTranslationState((IBinder) args.arg1, (int) args.arg2,
(TranslationSpec) args.arg3, (TranslationSpec) args.arg4,
- (List<AutofillId>) args.arg5);
+ (List<AutofillId>) args.arg5, (UiTranslationSpec) args.arg6);
break;
case SET_CONTENT_CAPTURE_OPTIONS_CALLBACK:
handleSetContentCaptureOptionsCallback((String) msg.obj);
@@ -4194,13 +4197,15 @@
}
private void updateUiTranslationState(IBinder activityToken, int state,
- TranslationSpec sourceSpec, TranslationSpec targetSpec, List<AutofillId> viewIds) {
+ TranslationSpec sourceSpec, TranslationSpec targetSpec, List<AutofillId> viewIds,
+ UiTranslationSpec uiTranslationSpec) {
final ActivityClientRecord r = mActivities.get(activityToken);
if (r == null) {
Log.w(TAG, "updateUiTranslationState(): no activity for " + activityToken);
return;
}
- r.activity.updateUiTranslationState(state, sourceSpec, targetSpec, viewIds);
+ r.activity.updateUiTranslationState(
+ state, sourceSpec, targetSpec, viewIds, uiTranslationSpec);
}
private static final ThreadLocal<Intent> sCurrentBroadcastIntent = new ThreadLocal<Intent>();
diff --git a/core/java/android/app/IApplicationThread.aidl b/core/java/android/app/IApplicationThread.aidl
index 918309e..4555c172 100644
--- a/core/java/android/app/IApplicationThread.aidl
+++ b/core/java/android/app/IApplicationThread.aidl
@@ -46,6 +46,7 @@
import android.os.SharedMemory;
import android.view.autofill.AutofillId;
import android.view.translation.TranslationSpec;
+import android.view.translation.UiTranslationSpec;
import com.android.internal.app.IVoiceInteractor;
import com.android.internal.content.ReferrerIntent;
@@ -160,5 +161,6 @@
IUiAutomationConnection instrumentationUiConnection,
in ApplicationInfo targetInfo);
void updateUiTranslationState(IBinder activityToken, int state, in TranslationSpec sourceSpec,
- in TranslationSpec targetSpec, in List<AutofillId> viewIds);
+ in TranslationSpec targetSpec, in List<AutofillId> viewIds,
+ in UiTranslationSpec uiTranslationSpec);
}
diff --git a/core/java/android/view/translation/UiTranslationController.java b/core/java/android/view/translation/UiTranslationController.java
index e0526f8..9e350d9 100644
--- a/core/java/android/view/translation/UiTranslationController.java
+++ b/core/java/android/view/translation/UiTranslationController.java
@@ -30,6 +30,7 @@
import android.os.HandlerThread;
import android.os.Process;
import android.util.ArrayMap;
+import android.util.ArraySet;
import android.util.IntArray;
import android.util.Log;
import android.util.LongSparseArray;
@@ -77,6 +78,11 @@
private final ArrayMap<Pair<TranslationSpec, TranslationSpec>, Translator> mTranslators;
@NonNull
private final ArrayMap<AutofillId, WeakReference<View>> mViews;
+ /**
+ * Views for which {@link UiTranslationSpec#shouldPadContentForCompat()} is true.
+ */
+ @NonNull
+ private final ArraySet<AutofillId> mViewsToPadContent;
@NonNull
private final HandlerThread mWorkerThread;
@NonNull
@@ -88,6 +94,7 @@
mContext = context;
mViews = new ArrayMap<>();
mTranslators = new ArrayMap<>();
+ mViewsToPadContent = new ArraySet<>();
mWorkerThread =
new HandlerThread("UiTranslationController_" + mActivity.getComponentName(),
@@ -100,19 +107,27 @@
* Update the Ui translation state.
*/
public void updateUiTranslationState(@UiTranslationState int state, TranslationSpec sourceSpec,
- TranslationSpec targetSpec, List<AutofillId> views) {
+ TranslationSpec targetSpec, List<AutofillId> views,
+ UiTranslationSpec uiTranslationSpec) {
if (!mActivity.isResumed() && (state == STATE_UI_TRANSLATION_STARTED
|| state == STATE_UI_TRANSLATION_RESUMED)) {
return;
}
Log.i(TAG, "updateUiTranslationState state: " + stateToString(state)
- + (DEBUG ? ", views: " + views : ""));
+ + (DEBUG ? (", views: " + views + ", spec: " + uiTranslationSpec) : ""));
synchronized (mLock) {
mCurrentState = state;
}
switch (state) {
case STATE_UI_TRANSLATION_STARTED:
+ if (uiTranslationSpec != null && uiTranslationSpec.shouldPadContentForCompat()) {
+ synchronized (mLock) {
+ mViewsToPadContent.addAll(views);
+ // TODO: Cleanup disappeared views from mViews and mViewsToPadContent at
+ // some appropriate place.
+ }
+ }
final Pair<TranslationSpec, TranslationSpec> specs =
new Pair<>(sourceSpec, targetSpec);
if (!mTranslators.containsKey(specs)) {
@@ -177,6 +192,7 @@
pw.print(pfx); pw.print("autofillId: "); pw.println(autofillId);
pw.print(pfx); pw.print("view:"); pw.println(view);
}
+ pw.print(outerPrefix); pw.print("padded views: "); pw.println(mViewsToPadContent);
}
// TODO(b/182433547): we will remove debug rom condition before S release then we change
// change this back to "DEBUG"
@@ -374,8 +390,9 @@
return;
}
- // TODO: Do this for specific views on request only.
- callback.enableContentPadding();
+ if (mViewsToPadContent.contains(autofillId)) {
+ callback.enableContentPadding();
+ }
view.onViewTranslationResponse(response);
callback.onShowTranslation(view);
});
diff --git a/core/tests/coretests/src/android/app/servertransaction/TransactionParcelTests.java b/core/tests/coretests/src/android/app/servertransaction/TransactionParcelTests.java
index 281ce2b..df0c64c 100644
--- a/core/tests/coretests/src/android/app/servertransaction/TransactionParcelTests.java
+++ b/core/tests/coretests/src/android/app/servertransaction/TransactionParcelTests.java
@@ -61,6 +61,7 @@
import android.view.Surface;
import android.view.autofill.AutofillId;
import android.view.translation.TranslationSpec;
+import android.view.translation.UiTranslationSpec;
import androidx.test.filters.SmallTest;
import androidx.test.runner.AndroidJUnit4;
@@ -693,8 +694,8 @@
@Override
public void updateUiTranslationState(IBinder activityToken, int state,
- TranslationSpec sourceSpec, TranslationSpec targetSpec, List<AutofillId> viewIds) {
-
+ TranslationSpec sourceSpec, TranslationSpec targetSpec, List<AutofillId> viewIds,
+ UiTranslationSpec uiTranslationSpec) {
}
}
}
diff --git a/services/translation/java/com/android/server/translation/TranslationManagerServiceImpl.java b/services/translation/java/com/android/server/translation/TranslationManagerServiceImpl.java
index 4198d3b..2b01cdf 100644
--- a/services/translation/java/com/android/server/translation/TranslationManagerServiceImpl.java
+++ b/services/translation/java/com/android/server/translation/TranslationManagerServiceImpl.java
@@ -175,10 +175,9 @@
return;
}
try {
- // TODO: Pipe uiTranslationSpec through to the UiTranslationController.
taskTopActivityTokens.getApplicationThread().updateUiTranslationState(
taskTopActivityTokens.getActivityToken(), state, sourceSpec, targetSpec,
- viewIds);
+ viewIds, uiTranslationSpec);
} catch (RemoteException e) {
Slog.w(TAG, "Update UiTranslationState fail: " + e);
}