Skip applying scale by local relaunch item

If a scaled app calls Activity#recreate(), it will perform
a local relaunch from ActivityThread#handleRelaunchActivityLocally.
That uses the current config to execute, which was already scaled.
So to avoid double scaling, do not apply the scale if the
transaction item is executing from local.

Fix: 264133971
Test: atest ActivityThreadTest#testOverrideScale

Change-Id: I0e8ed3b056506ae9e2059fa0263b420474829ae5
This commit is contained in:
Riddle Hsu
2023-01-04 10:04:02 +00:00
parent 099f82439d
commit 65d075524c
3 changed files with 33 additions and 4 deletions

View File

@@ -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;
}
/**

View File

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

View File

@@ -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(