Merge "Add minAspectRatio"
This commit is contained in:
@@ -940,6 +940,7 @@ package android {
|
||||
field public static final int menuCategory = 16843230; // 0x10101de
|
||||
field public static final int mimeType = 16842790; // 0x1010026
|
||||
field public static final int min = 16844089; // 0x1010539
|
||||
field public static final int minAspectRatio = 16844193; // 0x10105a1
|
||||
field public static final int minDate = 16843583; // 0x101033f
|
||||
field public static final int minEms = 16843098; // 0x101015a
|
||||
field public static final int minHeight = 16843072; // 0x1010140
|
||||
|
||||
@@ -235,6 +235,15 @@ public class ActivityInfo extends ComponentInfo implements Parcelable {
|
||||
*/
|
||||
public float maxAspectRatio;
|
||||
|
||||
/**
|
||||
* Value indicating the minimum aspect ratio the activity supports.
|
||||
* <p>
|
||||
* 0 means unset.
|
||||
* @See {@link android.R.attr#minAspectRatio}.
|
||||
* @hide
|
||||
*/
|
||||
public float minAspectRatio;
|
||||
|
||||
/**
|
||||
* Name of the VrListenerService component to run for this activity.
|
||||
* @see android.R.attr#enableVrMode
|
||||
@@ -979,6 +988,7 @@ public class ActivityInfo extends ComponentInfo implements Parcelable {
|
||||
rotationAnimation = orig.rotationAnimation;
|
||||
colorMode = orig.colorMode;
|
||||
maxAspectRatio = orig.maxAspectRatio;
|
||||
minAspectRatio = orig.minAspectRatio;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1142,6 +1152,9 @@ public class ActivityInfo extends ComponentInfo implements Parcelable {
|
||||
if (maxAspectRatio != 0) {
|
||||
pw.println(prefix + "maxAspectRatio=" + maxAspectRatio);
|
||||
}
|
||||
if (minAspectRatio != 0) {
|
||||
pw.println(prefix + "minAspectRatio=" + minAspectRatio);
|
||||
}
|
||||
super.dumpBack(pw, prefix, dumpFlags);
|
||||
}
|
||||
|
||||
@@ -1190,6 +1203,7 @@ public class ActivityInfo extends ComponentInfo implements Parcelable {
|
||||
dest.writeInt(rotationAnimation);
|
||||
dest.writeInt(colorMode);
|
||||
dest.writeFloat(maxAspectRatio);
|
||||
dest.writeFloat(minAspectRatio);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1309,6 +1323,7 @@ public class ActivityInfo extends ComponentInfo implements Parcelable {
|
||||
rotationAnimation = source.readInt();
|
||||
colorMode = source.readInt();
|
||||
maxAspectRatio = source.readFloat();
|
||||
minAspectRatio = source.readFloat();
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -712,6 +712,15 @@ public class ApplicationInfo extends PackageItemInfo implements Parcelable {
|
||||
*/
|
||||
public float maxAspectRatio;
|
||||
|
||||
/**
|
||||
* Value indicating the minimum aspect ratio the application supports.
|
||||
* <p>
|
||||
* 0 means unset.
|
||||
* @see {@link android.R.attr#minAspectRatio}.
|
||||
* @hide
|
||||
*/
|
||||
public float minAspectRatio;
|
||||
|
||||
/** @removed */
|
||||
@Deprecated
|
||||
public String volumeUuid;
|
||||
|
||||
@@ -30,6 +30,7 @@ import static android.content.pm.ApplicationInfo.FLAG_SUSPENDED;
|
||||
import static android.content.pm.ApplicationInfo.PRIVATE_FLAG_ACTIVITIES_RESIZE_MODE_RESIZEABLE;
|
||||
import static android.content.pm.ApplicationInfo.PRIVATE_FLAG_ACTIVITIES_RESIZE_MODE_RESIZEABLE_VIA_SDK_VERSION;
|
||||
import static android.content.pm.ApplicationInfo.PRIVATE_FLAG_ACTIVITIES_RESIZE_MODE_UNRESIZEABLE;
|
||||
import static android.content.pm.PackageManager.FEATURE_WATCH;
|
||||
import static android.content.pm.PackageManager.INSTALL_PARSE_FAILED_BAD_MANIFEST;
|
||||
import static android.content.pm.PackageManager.INSTALL_PARSE_FAILED_BAD_PACKAGE_NAME;
|
||||
import static android.content.pm.PackageManager.INSTALL_PARSE_FAILED_INCONSISTENT_CERTIFICATES;
|
||||
@@ -162,6 +163,8 @@ public class PackageParser {
|
||||
SystemProperties.getBoolean(PROPERTY_CHILD_PACKAGES_ENABLED, false);
|
||||
|
||||
private static final float DEFAULT_PRE_O_MAX_ASPECT_RATIO = 1.86f;
|
||||
private static final float DEFAULT_PRE_Q_MIN_ASPECT_RATIO = 1.333f;
|
||||
private static final float DEFAULT_PRE_Q_MIN_ASPECT_RATIO_WATCH = 1f;
|
||||
|
||||
// TODO: switch outError users to PackageParserException
|
||||
// TODO: refactor "codePath" to "apkPath"
|
||||
@@ -3673,6 +3676,7 @@ public class PackageParser {
|
||||
}
|
||||
|
||||
ai.maxAspectRatio = sa.getFloat(R.styleable.AndroidManifestApplication_maxAspectRatio, 0);
|
||||
ai.minAspectRatio = sa.getFloat(R.styleable.AndroidManifestApplication_minAspectRatio, 0);
|
||||
|
||||
ai.networkSecurityConfigRes = sa.getResourceId(
|
||||
com.android.internal.R.styleable.AndroidManifestApplication_networkSecurityConfig,
|
||||
@@ -3995,6 +3999,7 @@ public class PackageParser {
|
||||
// Must be ran after the entire {@link ApplicationInfo} has been fully processed and after
|
||||
// every activity info has had a chance to set it from its attributes.
|
||||
setMaxAspectRatio(owner);
|
||||
setMinAspectRatio(owner);
|
||||
|
||||
PackageBackwardCompatibility.modifySharedLibraries(owner);
|
||||
|
||||
@@ -4492,6 +4497,13 @@ public class PackageParser {
|
||||
0 /*default*/));
|
||||
}
|
||||
|
||||
if (sa.hasValue(R.styleable.AndroidManifestActivity_minAspectRatio)
|
||||
&& sa.getType(R.styleable.AndroidManifestActivity_minAspectRatio)
|
||||
== TypedValue.TYPE_FLOAT) {
|
||||
a.setMinAspectRatio(sa.getFloat(R.styleable.AndroidManifestActivity_minAspectRatio,
|
||||
0 /*default*/));
|
||||
}
|
||||
|
||||
a.info.lockTaskLaunchMode =
|
||||
sa.getInt(R.styleable.AndroidManifestActivity_lockTaskMode, 0);
|
||||
|
||||
@@ -4750,6 +4762,34 @@ public class PackageParser {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets every the max aspect ratio of every child activity that doesn't already have an aspect
|
||||
* ratio set.
|
||||
*/
|
||||
private void setMinAspectRatio(Package owner) {
|
||||
final float minAspectRatio;
|
||||
if (owner.applicationInfo.minAspectRatio != 0) {
|
||||
// Use the application max aspect ration as default if set.
|
||||
minAspectRatio = owner.applicationInfo.minAspectRatio;
|
||||
} else {
|
||||
// Default to (1.33) 4:3 aspect ratio for pre-Q apps and unset for Q and greater.
|
||||
// NOTE: 4:3 was the min aspect ratio Android devices can support pre-Q per the CDD,
|
||||
// except for watches which always supported 1:1.
|
||||
minAspectRatio = owner.applicationInfo.targetSdkVersion >= Build.VERSION_CODES.Q
|
||||
? 0
|
||||
: mCallback.hasFeature(FEATURE_WATCH)
|
||||
? DEFAULT_PRE_Q_MIN_ASPECT_RATIO_WATCH
|
||||
: DEFAULT_PRE_Q_MIN_ASPECT_RATIO;
|
||||
}
|
||||
|
||||
for (Activity activity : owner.activities) {
|
||||
if (activity.hasMinAspectRatio()) {
|
||||
continue;
|
||||
}
|
||||
activity.setMinAspectRatio(minAspectRatio);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param configChanges The bit mask of configChanges fetched from AndroidManifest.xml.
|
||||
* @param recreateOnConfigChanges The bit mask recreateOnConfigChanges fetched from
|
||||
@@ -4888,6 +4928,7 @@ public class PackageParser {
|
||||
info.windowLayout = target.info.windowLayout;
|
||||
info.resizeMode = target.info.resizeMode;
|
||||
info.maxAspectRatio = target.info.maxAspectRatio;
|
||||
info.minAspectRatio = target.info.minAspectRatio;
|
||||
info.requestedVrComponent = target.info.requestedVrComponent;
|
||||
|
||||
info.encryptionAware = info.directBootAware = target.info.directBootAware;
|
||||
@@ -7773,11 +7814,16 @@ public class PackageParser {
|
||||
@UnsupportedAppUsage
|
||||
public final ActivityInfo info;
|
||||
private boolean mHasMaxAspectRatio;
|
||||
private boolean mHasMinAspectRatio;
|
||||
|
||||
private boolean hasMaxAspectRatio() {
|
||||
return mHasMaxAspectRatio;
|
||||
}
|
||||
|
||||
private boolean hasMinAspectRatio() {
|
||||
return mHasMinAspectRatio;
|
||||
}
|
||||
|
||||
// To construct custom activity which does not exist in manifest
|
||||
Activity(final Package owner, final String className, final ActivityInfo info) {
|
||||
super(owner, new ArrayList<>(0), className);
|
||||
@@ -7813,6 +7859,22 @@ public class PackageParser {
|
||||
mHasMaxAspectRatio = true;
|
||||
}
|
||||
|
||||
private void setMinAspectRatio(float minAspectRatio) {
|
||||
if (info.resizeMode == RESIZE_MODE_RESIZEABLE
|
||||
|| info.resizeMode == RESIZE_MODE_RESIZEABLE_VIA_SDK_VERSION) {
|
||||
// Resizeable activities can be put in any aspect ratio.
|
||||
return;
|
||||
}
|
||||
|
||||
if (minAspectRatio < 1.0f && minAspectRatio != 0) {
|
||||
// Ignore any value lesser than 1.0.
|
||||
return;
|
||||
}
|
||||
|
||||
info.minAspectRatio = minAspectRatio;
|
||||
mHasMinAspectRatio = true;
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
StringBuilder sb = new StringBuilder(128);
|
||||
sb.append("Activity{");
|
||||
@@ -7833,12 +7895,14 @@ public class PackageParser {
|
||||
super.writeToParcel(dest, flags);
|
||||
dest.writeParcelable(info, flags | Parcelable.PARCELABLE_ELIDE_DUPLICATES);
|
||||
dest.writeBoolean(mHasMaxAspectRatio);
|
||||
dest.writeBoolean(mHasMinAspectRatio);
|
||||
}
|
||||
|
||||
private Activity(Parcel in) {
|
||||
super(in);
|
||||
info = in.readParcelable(Object.class.getClassLoader());
|
||||
mHasMaxAspectRatio = in.readBoolean();
|
||||
mHasMinAspectRatio = in.readBoolean();
|
||||
|
||||
for (ActivityIntentInfo aii : intents) {
|
||||
aii.activity = this;
|
||||
|
||||
@@ -1294,6 +1294,20 @@
|
||||
supports any size. -->
|
||||
<attr name="maxAspectRatio" format="float" />
|
||||
|
||||
<!-- This value indicates the minimum aspect ratio the activity supports. If the app runs on a
|
||||
device with a narrower aspect ratio, the system automatically letterboxes the app, leaving
|
||||
portions of the screen unused so the app can run at its specified minimum aspect ratio.
|
||||
<p>
|
||||
Minimum aspect ratio, expressed as (longer dimension / shorter dimension) in decimal
|
||||
form. For example, if the minimum aspect ratio is 4:3, set value to 1.33.
|
||||
<p>
|
||||
Value needs to be greater or equal to 1.0, otherwise it is ignored.
|
||||
<p>
|
||||
NOTE: This attribute is ignored if the activity has
|
||||
{@link android.R.attr#resizeableActivity} set to true, since that means your activity
|
||||
supports any size. -->
|
||||
<attr name="minAspectRatio" format="float" />
|
||||
|
||||
<!-- This value indicates how tasks rooted at this activity will behave in lockTask mode.
|
||||
While in lockTask mode the system will not launch non-permitted tasks until
|
||||
lockTask mode is disabled.
|
||||
@@ -1571,6 +1585,7 @@
|
||||
<attr name="directBootAware" />
|
||||
<attr name="resizeableActivity" />
|
||||
<attr name="maxAspectRatio" />
|
||||
<attr name="minAspectRatio" />
|
||||
<attr name="networkSecurityConfig" />
|
||||
<!-- Declare the category of this app. Categories are used to cluster multiple apps
|
||||
together into meaningful groups, such as when summarizing battery, network, or
|
||||
@@ -2386,6 +2401,7 @@
|
||||
<attr name="resizeableActivity" />
|
||||
<attr name="supportsPictureInPicture" />
|
||||
<attr name="maxAspectRatio" />
|
||||
<attr name="minAspectRatio" />
|
||||
<attr name="lockTaskMode" />
|
||||
<attr name="showForAllUsers" />
|
||||
|
||||
|
||||
@@ -2931,6 +2931,7 @@
|
||||
<public name="selectionDividerHeight" />
|
||||
<public name="foregroundServiceType" />
|
||||
<public name="hasFragileUserData" />
|
||||
<public name="minAspectRatio" />
|
||||
</public-group>
|
||||
|
||||
<public-group type="drawable" first-id="0x010800b4">
|
||||
|
||||
@@ -86,6 +86,7 @@ import static android.os.Build.VERSION_CODES.O;
|
||||
import static android.os.Process.SYSTEM_UID;
|
||||
import static android.view.Display.INVALID_DISPLAY;
|
||||
import static android.view.WindowManagerPolicyConstants.NAV_BAR_LEFT;
|
||||
import static android.view.WindowManagerPolicyConstants.NAV_BAR_RIGHT;
|
||||
|
||||
import static com.android.server.am.ActivityRecordProto.CONFIGURATION_CONTAINER;
|
||||
import static com.android.server.am.ActivityRecordProto.FRONT_OF_TASK;
|
||||
@@ -583,6 +584,9 @@ final class ActivityRecord extends ConfigurationContainer {
|
||||
if (info.maxAspectRatio != 0) {
|
||||
pw.println(prefix + "maxAspectRatio=" + info.maxAspectRatio);
|
||||
}
|
||||
if (info.minAspectRatio != 0) {
|
||||
pw.println(prefix + "minAspectRatio=" + info.minAspectRatio);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2593,7 +2597,10 @@ final class ActivityRecord extends ConfigurationContainer {
|
||||
outBounds.setEmpty();
|
||||
final float maxAspectRatio = info.maxAspectRatio;
|
||||
final ActivityStack stack = getActivityStack();
|
||||
if (task == null || stack == null || task.inMultiWindowMode() || maxAspectRatio == 0
|
||||
final float minAspectRatio = info.minAspectRatio;
|
||||
|
||||
if (task == null || stack == null || task.inMultiWindowMode()
|
||||
|| (maxAspectRatio == 0 && minAspectRatio == 0)
|
||||
|| isInVrUiMode(getConfiguration())) {
|
||||
// We don't set override configuration if that activity task isn't fullscreen. I.e. the
|
||||
// activity is in multi-window mode. Or, there isn't a max aspect ratio specified for
|
||||
@@ -2608,20 +2615,35 @@ final class ActivityRecord extends ConfigurationContainer {
|
||||
final Rect appBounds = getParent().getWindowConfiguration().getAppBounds();
|
||||
final int containingAppWidth = appBounds.width();
|
||||
final int containingAppHeight = appBounds.height();
|
||||
int maxActivityWidth = containingAppWidth;
|
||||
int maxActivityHeight = containingAppHeight;
|
||||
final float containingRatio = Math.max(containingAppWidth, containingAppHeight)
|
||||
/ (float) Math.min(containingAppWidth, containingAppHeight);
|
||||
|
||||
if (containingAppWidth < containingAppHeight) {
|
||||
// Width is the shorter side, so we use that to figure-out what the max. height
|
||||
// should be given the aspect ratio.
|
||||
maxActivityHeight = (int) ((maxActivityWidth * maxAspectRatio) + 0.5f);
|
||||
} else {
|
||||
// Height is the shorter side, so we use that to figure-out what the max. width
|
||||
// should be given the aspect ratio.
|
||||
maxActivityWidth = (int) ((maxActivityHeight * maxAspectRatio) + 0.5f);
|
||||
int activityWidth = containingAppWidth;
|
||||
int activityHeight = containingAppHeight;
|
||||
|
||||
if (containingRatio > maxAspectRatio && maxAspectRatio != 0) {
|
||||
if (containingAppWidth < containingAppHeight) {
|
||||
// Width is the shorter side, so we use that to figure-out what the max. height
|
||||
// should be given the aspect ratio.
|
||||
activityHeight = (int) ((activityWidth * maxAspectRatio) + 0.5f);
|
||||
} else {
|
||||
// Height is the shorter side, so we use that to figure-out what the max. width
|
||||
// should be given the aspect ratio.
|
||||
activityWidth = (int) ((activityHeight * maxAspectRatio) + 0.5f);
|
||||
}
|
||||
} else if (containingRatio < minAspectRatio && minAspectRatio != 0) {
|
||||
if (containingAppWidth < containingAppHeight) {
|
||||
// Width is the shorter side, so we use the height to figure-out what the max. width
|
||||
// should be given the aspect ratio.
|
||||
activityWidth = (int) ((activityHeight / minAspectRatio) + 0.5f);
|
||||
} else {
|
||||
// Height is the shorter side, so we use the width to figure-out what the max.
|
||||
// height should be given the aspect ratio.
|
||||
activityHeight = (int) ((activityWidth / minAspectRatio) + 0.5f);
|
||||
}
|
||||
}
|
||||
|
||||
if (containingAppWidth <= maxActivityWidth && containingAppHeight <= maxActivityHeight) {
|
||||
if (containingAppWidth <= activityWidth && containingAppHeight <= activityHeight) {
|
||||
// The display matches or is less than the activity aspect ratio, so nothing else to do.
|
||||
// Return the existing bounds. If this method is running for the first time,
|
||||
// {@link #getRequestedOverrideBounds()} will be empty (representing no override). If
|
||||
@@ -2636,12 +2658,21 @@ final class ActivityRecord extends ConfigurationContainer {
|
||||
// Also account for the left / top insets (e.g. from display cutouts), which will be clipped
|
||||
// away later in StackWindowController.adjustConfigurationForBounds(). Otherwise, the app
|
||||
// bounds would end up too small.
|
||||
outBounds.set(0, 0, maxActivityWidth + appBounds.left, maxActivityHeight + appBounds.top);
|
||||
outBounds.set(0, 0, activityWidth + appBounds.left, activityHeight + appBounds.top);
|
||||
|
||||
if (mAtmService.mWindowManager.getNavBarPosition(getDisplayId()) == NAV_BAR_LEFT) {
|
||||
final int navBarPosition = mAtmService.mWindowManager.getNavBarPosition(getDisplayId());
|
||||
if (navBarPosition == NAV_BAR_LEFT) {
|
||||
// Position the activity frame on the opposite side of the nav bar.
|
||||
outBounds.left = appBounds.right - maxActivityWidth;
|
||||
outBounds.left = appBounds.right - activityWidth;
|
||||
outBounds.right = appBounds.right;
|
||||
} else if (navBarPosition == NAV_BAR_RIGHT) {
|
||||
// Position the activity frame on the opposite side of the nav bar.
|
||||
outBounds.left = 0;
|
||||
outBounds.right = activityWidth + appBounds.left;
|
||||
} else {
|
||||
// Horizontally center the frame.
|
||||
outBounds.left = appBounds.left + (containingAppWidth - activityWidth) / 2;
|
||||
outBounds.right = outBounds.left + activityWidth;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user