diff --git a/core/java/android/app/ClientTransactionHandler.java b/core/java/android/app/ClientTransactionHandler.java index 3ba578371ea78..1b69b734ba402 100644 --- a/core/java/android/app/ClientTransactionHandler.java +++ b/core/java/android/app/ClientTransactionHandler.java @@ -42,6 +42,8 @@ import java.util.Map; */ public abstract class ClientTransactionHandler { + private boolean mIsExecutingLocalTransaction; + // Schedule phase related logic and handlers. /** Prepare and schedule transaction for execution. */ @@ -56,9 +58,19 @@ public abstract class ClientTransactionHandler { */ @VisibleForTesting public void executeTransaction(ClientTransaction transaction) { - transaction.preExecute(this); - getTransactionExecutor().execute(transaction); - transaction.recycle(); + mIsExecutingLocalTransaction = true; + try { + transaction.preExecute(this); + getTransactionExecutor().execute(transaction); + } finally { + mIsExecutingLocalTransaction = false; + transaction.recycle(); + } + } + + /** Returns {@code true} if the current executing ClientTransaction is from local request. */ + public boolean isExecutingLocalTransaction() { + return mIsExecutingLocalTransaction; } /** diff --git a/core/java/android/app/servertransaction/ActivityRelaunchItem.java b/core/java/android/app/servertransaction/ActivityRelaunchItem.java index c09461c1fb52e..b26dac7126098 100644 --- a/core/java/android/app/servertransaction/ActivityRelaunchItem.java +++ b/core/java/android/app/servertransaction/ActivityRelaunchItem.java @@ -57,7 +57,10 @@ public class ActivityRelaunchItem extends ActivityTransactionItem { @Override public void preExecute(ClientTransactionHandler client, IBinder token) { - CompatibilityInfo.applyOverrideScaleIfNeeded(mConfig); + // The local config is already scaled so only apply if this item is from server side. + if (!client.isExecutingLocalTransaction()) { + CompatibilityInfo.applyOverrideScaleIfNeeded(mConfig); + } mActivityClientRecord = client.prepareRelaunchActivity(token, mPendingResults, mPendingNewIntents, mConfigChanges, mConfig, mPreserveWindow); } diff --git a/core/tests/coretests/src/android/app/activity/ActivityThreadTest.java b/core/tests/coretests/src/android/app/activity/ActivityThreadTest.java index 9db88051542b1..6c58d92319491 100644 --- a/core/tests/coretests/src/android/app/activity/ActivityThreadTest.java +++ b/core/tests/coretests/src/android/app/activity/ActivityThreadTest.java @@ -228,6 +228,20 @@ public class ActivityThreadTest { InstrumentationRegistry.getInstrumentation().waitForIdleSync(); assertScreenScale(scale, activity, originalActivityConfig, originalActivityMetrics); + + // Execute a local relaunch item with current scaled config (e.g. simulate recreate), + // the config should not be scaled again. + final Configuration currentConfig = activity.getResources().getConfiguration(); + final ClientTransaction localTransaction = + newTransaction(activityThread, activity.getActivityToken()); + localTransaction.addCallback(ActivityRelaunchItem.obtain( + null /* pendingResults */, null /* pendingIntents */, 0 /* configChanges */, + new MergedConfiguration(currentConfig, currentConfig), + true /* preserveWindow */)); + InstrumentationRegistry.getInstrumentation().runOnMainSync( + () -> activityThread.executeTransaction(localTransaction)); + + assertScreenScale(scale, activity, originalActivityConfig, originalActivityMetrics); } finally { CompatibilityInfo.setOverrideInvertedScale(originalScale); InstrumentationRegistry.getInstrumentation().runOnMainSync(