Apply override scale from entry points on client
This provides a sandbox-like scaled environment on client side.
- This prevents the metrics and config from being scaled multiple
times because the entry points are only called from server side,
there won't have reentrancy for applying the scale.
- App's configuration callback method can get scaled config.
- If override scale is enabled, the legacy compat mode will be
skipped. That avoids mixing different approaches of scaling.
- Legacy compat mode is to simulate a 320dp x 480dp screen
size with density 160 (the surface scale and config scale
are different).
- Override scale is to downscale the app for better performance
(the surface scale and config scale are the same).
Bug: 238416387
Bug: 240335717
Test: atest ActivityThreadTest#testOverrideScale
Test: atest CtsWindowManagerDeviceTestCases:CompatScaleTests
Test: am compat enable DOWNSCALED $pkg
am compat enable DOWNSCALE_50 $pkg
Change-Id: I0ddf333996f229063511273f8aeb3867c9ba8bda
This commit is contained in:
@@ -1177,9 +1177,16 @@ public final class ActivityThread extends ClientTransactionHandler
|
||||
data.mSerializedSystemFontMap = serializedSystemFontMap;
|
||||
data.startRequestedElapsedTime = startRequestedElapsedTime;
|
||||
data.startRequestedUptime = startRequestedUptime;
|
||||
updateCompatOverrideScale(compatInfo);
|
||||
CompatibilityInfo.applyOverrideScaleIfNeeded(config);
|
||||
sendMessage(H.BIND_APPLICATION, data);
|
||||
}
|
||||
|
||||
private void updateCompatOverrideScale(CompatibilityInfo info) {
|
||||
CompatibilityInfo.setOverrideInvertedScale(
|
||||
info.hasOverrideScaling() ? info.applicationInvertedScale : 1f);
|
||||
}
|
||||
|
||||
public final void runIsolatedEntryPoint(String entryPoint, String[] entryPointArgs) {
|
||||
SomeArgs args = SomeArgs.obtain();
|
||||
args.arg1 = entryPoint;
|
||||
@@ -1756,6 +1763,7 @@ public final class ActivityThread extends ClientTransactionHandler
|
||||
UpdateCompatibilityData ucd = new UpdateCompatibilityData();
|
||||
ucd.pkg = pkg;
|
||||
ucd.info = info;
|
||||
updateCompatOverrideScale(info);
|
||||
sendMessage(H.UPDATE_PACKAGE_COMPATIBILITY_INFO, ucd);
|
||||
}
|
||||
|
||||
|
||||
@@ -462,13 +462,30 @@ public class WindowConfiguration implements Parcelable, Comparable<WindowConfigu
|
||||
|
||||
/** @hide */
|
||||
public void scale(float scale) {
|
||||
mBounds.scale(scale);
|
||||
mMaxBounds.scale(scale);
|
||||
scaleBounds(scale, mBounds);
|
||||
scaleBounds(scale, mMaxBounds);
|
||||
if (mAppBounds != null) {
|
||||
mAppBounds.scale(scale);
|
||||
scaleBounds(scale, mAppBounds);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Size based scaling. This avoid inconsistent length when rounding 4 sides.
|
||||
* E.g. left=12, right=18, scale=0.8. The scaled width can be:
|
||||
* int((right - left) * scale + 0.5) = int(4.8 + 0.5) = 5
|
||||
* But with rounding both left and right, the width will be inconsistent:
|
||||
* int(right * scale + 0.5) - int(left * scale + 0.5) = int(14.9) - int(10.1) = 4
|
||||
* @hide
|
||||
*/
|
||||
private static void scaleBounds(float scale, Rect bounds) {
|
||||
final int w = bounds.width();
|
||||
final int h = bounds.height();
|
||||
bounds.left = (int) (bounds.left * scale + .5f);
|
||||
bounds.top = (int) (bounds.top * scale + .5f);
|
||||
bounds.right = bounds.left + (int) (w * scale + .5f);
|
||||
bounds.bottom = bounds.top + (int) (h * scale + .5f);
|
||||
}
|
||||
|
||||
/**
|
||||
* Copies the fields from delta into this Configuration object, keeping
|
||||
* track of which ones have changed. Any undefined fields in {@code delta}
|
||||
|
||||
@@ -23,6 +23,7 @@ import android.annotation.NonNull;
|
||||
import android.annotation.Nullable;
|
||||
import android.app.ActivityThread.ActivityClientRecord;
|
||||
import android.app.ClientTransactionHandler;
|
||||
import android.content.res.CompatibilityInfo;
|
||||
import android.content.res.Configuration;
|
||||
import android.os.IBinder;
|
||||
import android.os.Parcel;
|
||||
@@ -40,6 +41,7 @@ public class ActivityConfigurationChangeItem extends ActivityTransactionItem {
|
||||
|
||||
@Override
|
||||
public void preExecute(android.app.ClientTransactionHandler client, IBinder token) {
|
||||
CompatibilityInfo.applyOverrideScaleIfNeeded(mConfiguration);
|
||||
// Notify the client of an upcoming change in the token configuration. This ensures that
|
||||
// batches of config change items only process the newest configuration.
|
||||
client.updatePendingActivityConfiguration(token, mConfiguration);
|
||||
|
||||
@@ -23,6 +23,7 @@ import android.annotation.Nullable;
|
||||
import android.app.ActivityThread.ActivityClientRecord;
|
||||
import android.app.ClientTransactionHandler;
|
||||
import android.app.ResultInfo;
|
||||
import android.content.res.CompatibilityInfo;
|
||||
import android.os.IBinder;
|
||||
import android.os.Parcel;
|
||||
import android.os.Trace;
|
||||
@@ -56,6 +57,7 @@ public class ActivityRelaunchItem extends ActivityTransactionItem {
|
||||
|
||||
@Override
|
||||
public void preExecute(ClientTransactionHandler client, IBinder token) {
|
||||
CompatibilityInfo.applyOverrideScaleIfNeeded(mConfig);
|
||||
mActivityClientRecord = client.prepareRelaunchActivity(token, mPendingResults,
|
||||
mPendingNewIntents, mConfigChanges, mConfig, mPreserveWindow);
|
||||
}
|
||||
|
||||
@@ -18,6 +18,7 @@ package android.app.servertransaction;
|
||||
|
||||
import android.annotation.Nullable;
|
||||
import android.app.ClientTransactionHandler;
|
||||
import android.content.res.CompatibilityInfo;
|
||||
import android.content.res.Configuration;
|
||||
import android.os.IBinder;
|
||||
import android.os.Parcel;
|
||||
@@ -34,6 +35,7 @@ public class ConfigurationChangeItem extends ClientTransactionItem {
|
||||
|
||||
@Override
|
||||
public void preExecute(android.app.ClientTransactionHandler client, IBinder token) {
|
||||
CompatibilityInfo.applyOverrideScaleIfNeeded(mConfiguration);
|
||||
client.updatePendingConfiguration(mConfiguration);
|
||||
}
|
||||
|
||||
|
||||
@@ -30,6 +30,7 @@ import android.app.ResultInfo;
|
||||
import android.compat.annotation.UnsupportedAppUsage;
|
||||
import android.content.Intent;
|
||||
import android.content.pm.ActivityInfo;
|
||||
import android.content.res.CompatibilityInfo;
|
||||
import android.content.res.Configuration;
|
||||
import android.os.BaseBundle;
|
||||
import android.os.Bundle;
|
||||
@@ -81,6 +82,8 @@ public class LaunchActivityItem extends ClientTransactionItem {
|
||||
public void preExecute(ClientTransactionHandler client, IBinder token) {
|
||||
client.countLaunchingActivities(1);
|
||||
client.updateProcessState(mProcState, false);
|
||||
CompatibilityInfo.applyOverrideScaleIfNeeded(mCurConfig);
|
||||
CompatibilityInfo.applyOverrideScaleIfNeeded(mOverrideConfig);
|
||||
client.updatePendingConfiguration(mCurConfig);
|
||||
if (mActivityClientController != null) {
|
||||
ActivityClient.setActivityClientController(mActivityClientController);
|
||||
|
||||
@@ -22,6 +22,7 @@ import android.annotation.NonNull;
|
||||
import android.annotation.Nullable;
|
||||
import android.app.ActivityThread.ActivityClientRecord;
|
||||
import android.app.ClientTransactionHandler;
|
||||
import android.content.res.CompatibilityInfo;
|
||||
import android.content.res.Configuration;
|
||||
import android.os.IBinder;
|
||||
import android.os.Parcel;
|
||||
@@ -40,6 +41,7 @@ public class MoveToDisplayItem extends ActivityTransactionItem {
|
||||
|
||||
@Override
|
||||
public void preExecute(ClientTransactionHandler client, IBinder token) {
|
||||
CompatibilityInfo.applyOverrideScaleIfNeeded(mConfiguration);
|
||||
// Notify the client of an upcoming change in the token configuration. This ensures that
|
||||
// batches of config change items only process the newest configuration.
|
||||
client.updatePendingActivityConfiguration(token, mConfiguration);
|
||||
|
||||
Reference in New Issue
Block a user