Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 58cb974e authored by Wale Ogunwale's avatar Wale Ogunwale Committed by Android (Google) Code Review
Browse files

Merge "Introducing WindowConfiguration"

parents 997eafcb 822e5121
Loading
Loading
Loading
Loading
+19 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2017 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License
 */

package android.app;

parcelable WindowConfiguration;
+225 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2017 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package android.app;

import android.annotation.IntDef;
import android.annotation.NonNull;
import android.content.res.Configuration;
import android.graphics.Rect;
import android.os.Parcel;
import android.os.Parcelable;
import android.view.DisplayInfo;

import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;

/**
 * Class that contains windowing configuration/state for other objects that contain windows directly
 * or indirectly. E.g. Activities, Task, Displays, ...
 * The test class is {@link com.android.server.wm.WindowConfigurationTests} which must be kept
 * up-to-date and ran anytime changes are made to this class.
 * @hide
 */
public class WindowConfiguration implements Parcelable, Comparable<WindowConfiguration> {

    /**
     * {@link android.graphics.Rect} defining app bounds. The dimensions override usages of
     * {@link DisplayInfo#appHeight} and {@link DisplayInfo#appWidth} and mirrors these values at
     * the display level. Lower levels can override these values to provide custom bounds to enforce
     * features such as a max aspect ratio.
     */
    private Rect mAppBounds;

    @IntDef(flag = true,
            value = {
                    WINDOW_CONFIG_APP_BOUNDS,
            })
    @Retention(RetentionPolicy.SOURCE)
    public @interface WindowConfig {}

    /** Bit that indicates that the {@link #mAppBounds} changed. */
    public static final int WINDOW_CONFIG_APP_BOUNDS = 1 << 0;

    public WindowConfiguration() {
        unset();
    }

    public WindowConfiguration(WindowConfiguration configuration) {
        setTo(configuration);
    }

    private WindowConfiguration(Parcel in) {
        readFromParcel(in);
    }

    @Override
    public void writeToParcel(Parcel dest, int flags) {
        dest.writeParcelable(mAppBounds, flags);
    }

    private void readFromParcel(Parcel source) {
        mAppBounds = source.readParcelable(Rect.class.getClassLoader());
    }

    @Override
    public int describeContents() {
        return 0;
    }

    public static final Creator<WindowConfiguration> CREATOR = new Creator<WindowConfiguration>() {
        @Override
        public WindowConfiguration createFromParcel(Parcel in) {
            return new WindowConfiguration(in);
        }

        @Override
        public WindowConfiguration[] newArray(int size) {
            return new WindowConfiguration[size];
        }
    };

    /**
     * Set {@link #mAppBounds} to the input Rect.
     * @param rect The rect value to set {@link #mAppBounds} to.
     * @see #getAppBounds()
     */
    public void setAppBounds(Rect rect) {
        if (rect == null) {
            mAppBounds = null;
            return;
        }

        setAppBounds(rect.left, rect.top, rect.right, rect.bottom);
    }

    /**
     * @see #setAppBounds(Rect)
     * @see #getAppBounds()
     */
    public void setAppBounds(int left, int top, int right, int bottom) {
        if (mAppBounds == null) {
            mAppBounds = new Rect();
        }

        mAppBounds.set(left, top, right, bottom);
    }

    /**
     * @see #setAppBounds(Rect)
     */
    public Rect getAppBounds() {
        return mAppBounds;
    }

    public void setTo(WindowConfiguration other) {
        setAppBounds(other.mAppBounds);
    }

    /** Set this object to completely undefined. */
    public void unset() {
        setToDefaults();
    }

    public void setToDefaults() {
        setAppBounds(null);
    }

    /**
     * Copies the fields from delta into this Configuration object, keeping
     * track of which ones have changed. Any undefined fields in {@code delta}
     * are ignored and not copied in to the current Configuration.
     *
     * @return a bit mask of the changed fields, as per {@link #diff}
     */
    public @WindowConfig int updateFrom(@NonNull WindowConfiguration delta) {
        int changed = 0;
        if (delta.mAppBounds != null && !delta.mAppBounds.equals(mAppBounds)) {
            changed |= WINDOW_CONFIG_APP_BOUNDS;
            setAppBounds(delta.mAppBounds);
        }
        return changed;
    }

    /**
     * Return a bit mask of the differences between this Configuration object and the given one.
     * Does not change the values of either. Any undefined fields in <var>other</var> are ignored.
     * @param other The configuration to diff against.
     * @param compareUndefined If undefined values should be compared.
     * @return Returns a bit mask indicating which configuration
     * values has changed, containing any combination of {@link WindowConfig} flags.
     *
     * @see Configuration#diff(Configuration)
     */
    public @WindowConfig long diff(WindowConfiguration other, boolean compareUndefined) {
        long changes = 0;

        // Make sure that one of the values is not null and that they are not equal.
        if ((compareUndefined || other.mAppBounds != null)
                && mAppBounds != other.mAppBounds
                && (mAppBounds == null || !mAppBounds.equals(other.mAppBounds))) {
            changes |= WINDOW_CONFIG_APP_BOUNDS;
        }

        return changes;
    }

    @Override
    public int compareTo(WindowConfiguration that) {
        int n = 0;
        if (mAppBounds == null && that.mAppBounds != null) {
            return 1;
        } else if (mAppBounds != null && that.mAppBounds == null) {
            return -1;
        } else if (mAppBounds != null && that.mAppBounds != null) {
            n = mAppBounds.left - that.mAppBounds.left;
            if (n != 0) return n;
            n = mAppBounds.top - that.mAppBounds.top;
            if (n != 0) return n;
            n = mAppBounds.right - that.mAppBounds.right;
            if (n != 0) return n;
            n = mAppBounds.bottom - that.mAppBounds.bottom;
            if (n != 0) return n;
        }

        // if (n != 0) return n;
        return n;
    }

    @Override
    public boolean equals(Object that) {
        if (that == null) return false;
        if (that == this) return true;
        if (!(that instanceof WindowConfiguration)) {
            return false;
        }
        return this.compareTo((WindowConfiguration) that) == 0;
    }

    @Override
    public int hashCode() {
        int result = 0;
        if (mAppBounds != null) {
            result = 31 * result + mAppBounds.hashCode();
        }
        return result;
    }

    @Override
    public String toString() {
        return "{mAppBounds=" + mAppBounds + "}";
    }
}
+7 −0
Original line number Diff line number Diff line
@@ -780,6 +780,13 @@ public class ActivityInfo extends ComponentInfo
     * constant starts at the high bits.
     */
    public static final int CONFIG_FONT_SCALE = 0x40000000;
    /**
     * Bit indicating changes to window configuration that isn't exposed to apps.
     * This is for internal use only and apps don't handle it.
     * @hide
     * {@link Configuration}.
     */
    public static final int CONFIG_WINDOW_CONFIGURATION = 0x20000000;

    /** @hide
     * Unfortunately the constants for config changes in native code are
+27 −79
Original line number Diff line number Diff line
@@ -19,15 +19,14 @@ package android.content.res;
import android.annotation.IntDef;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.app.WindowConfiguration;
import android.content.pm.ActivityInfo;
import android.content.pm.ActivityInfo.Config;
import android.graphics.Rect;
import android.os.Build;
import android.os.LocaleList;
import android.os.Parcel;
import android.os.Parcelable;
import android.text.TextUtils;
import android.view.DisplayInfo;
import android.view.View;

import com.android.internal.util.XmlUtils;
@@ -42,7 +41,6 @@ import java.lang.annotation.RetentionPolicy;
import java.util.ArrayList;
import java.util.Locale;


/**
 * This class describes all device configuration information that can
 * impact the resources the application retrieves.  This includes both
@@ -298,13 +296,11 @@ public final class Configuration implements Parcelable, Comparable<Configuration

    /**
     * @hide
     * {@link android.graphics.Rect} defining app bounds. The dimensions override usages of
     * {@link DisplayInfo#appHeight} and {@link DisplayInfo#appWidth} and mirrors these values at
     * the display level. Lower levels can override these values to provide custom bounds to enforce
     * features such as a max aspect ratio.
     * TODO(b/36812336): Move appBounds out of {@link Configuration}.
     * Configuration relating to the windowing state of the object associated with this
     * Configuration. Contents of this field are not intended to affect resources, but need to be
     * communicated and propagated at the same time as the rest of Configuration.
     */
    public Rect appBounds;
    public final WindowConfiguration windowConfiguration = new WindowConfiguration();

    /** @hide */
    static public int resetScreenLayout(int curLayout) {
@@ -895,9 +891,9 @@ public final class Configuration implements Parcelable, Comparable<Configuration
        compatScreenWidthDp = o.compatScreenWidthDp;
        compatScreenHeightDp = o.compatScreenHeightDp;
        compatSmallestScreenWidthDp = o.compatSmallestScreenWidthDp;
        setAppBounds(o.appBounds);
        assetsSeq = o.assetsSeq;
        seq = o.seq;
        windowConfiguration.setTo(o.windowConfiguration);
    }

    public String toString() {
@@ -1046,9 +1042,7 @@ public final class Configuration implements Parcelable, Comparable<Configuration
            case NAVIGATIONHIDDEN_YES: sb.append("/h"); break;
            default: sb.append("/"); sb.append(navigationHidden); break;
        }
        if (appBounds != null) {
            sb.append(" appBounds="); sb.append(appBounds);
        }
        sb.append(" winConfig="); sb.append(windowConfiguration);
        if (assetsSeq != 0) {
            sb.append(" as.").append(assetsSeq);
        }
@@ -1083,8 +1077,8 @@ public final class Configuration implements Parcelable, Comparable<Configuration
        smallestScreenWidthDp = compatSmallestScreenWidthDp = SMALLEST_SCREEN_WIDTH_DP_UNDEFINED;
        densityDpi = DENSITY_DPI_UNDEFINED;
        assetsSeq = ASSETS_SEQ_UNDEFINED;
        appBounds = null;
        seq = 0;
        windowConfiguration.setToDefaults();
    }

    /**
@@ -1183,7 +1177,6 @@ public final class Configuration implements Parcelable, Comparable<Configuration
            changed |= ActivityInfo.CONFIG_ORIENTATION;
            orientation = delta.orientation;
        }

        if (((delta.screenLayout & SCREENLAYOUT_SIZE_MASK) != SCREENLAYOUT_SIZE_UNDEFINED)
                && (delta.screenLayout & SCREENLAYOUT_SIZE_MASK)
                != (screenLayout & SCREENLAYOUT_SIZE_MASK)) {
@@ -1271,10 +1264,6 @@ public final class Configuration implements Parcelable, Comparable<Configuration
        if (delta.compatSmallestScreenWidthDp != SMALLEST_SCREEN_WIDTH_DP_UNDEFINED) {
            compatSmallestScreenWidthDp = delta.compatSmallestScreenWidthDp;
        }
        if (delta.appBounds != null && !delta.appBounds.equals(appBounds)) {
            changed |= ActivityInfo.CONFIG_SCREEN_SIZE;
            setAppBounds(delta.appBounds);
        }
        if (delta.assetsSeq != ASSETS_SEQ_UNDEFINED && delta.assetsSeq != assetsSeq) {
            changed |= ActivityInfo.CONFIG_ASSETS_PATHS;
            assetsSeq = delta.assetsSeq;
@@ -1282,6 +1271,9 @@ public final class Configuration implements Parcelable, Comparable<Configuration
        if (delta.seq != 0) {
            seq = delta.seq;
        }
        if (windowConfiguration.updateFrom(delta.windowConfiguration) != 0) {
            changed |= ActivityInfo.CONFIG_WINDOW_CONFIGURATION;
        }

        return changed;
    }
@@ -1433,13 +1425,10 @@ public final class Configuration implements Parcelable, Comparable<Configuration
            changed |= ActivityInfo.CONFIG_ASSETS_PATHS;
        }

        // Make sure that one of the values is not null and that they are not equal.
        if ((compareUndefined || delta.appBounds != null)
                && appBounds != delta.appBounds
                && (appBounds == null || (!publicOnly && !appBounds.equals(delta.appBounds))
                        || (publicOnly && (appBounds.width() != delta.appBounds.width()
                                || appBounds.height() != delta.appBounds.height())))) {
            changed |= ActivityInfo.CONFIG_SCREEN_SIZE;
        // WindowConfiguration differences aren't considered public...
        if (!publicOnly
                && windowConfiguration.diff(delta.windowConfiguration, compareUndefined) != 0) {
            changed |= ActivityInfo.CONFIG_WINDOW_CONFIGURATION;
        }

        return changed;
@@ -1537,7 +1526,7 @@ public final class Configuration implements Parcelable, Comparable<Configuration
        dest.writeInt(compatScreenWidthDp);
        dest.writeInt(compatScreenHeightDp);
        dest.writeInt(compatSmallestScreenWidthDp);
        dest.writeValue(appBounds);
        dest.writeValue(windowConfiguration);
        dest.writeInt(assetsSeq);
        dest.writeInt(seq);
    }
@@ -1573,7 +1562,7 @@ public final class Configuration implements Parcelable, Comparable<Configuration
        compatScreenWidthDp = source.readInt();
        compatScreenHeightDp = source.readInt();
        compatSmallestScreenWidthDp = source.readInt();
        appBounds = (Rect) source.readValue(null);
        windowConfiguration.setTo((WindowConfiguration) source.readValue(null));
        assetsSeq = source.readInt();
        seq = source.readInt();
    }
@@ -1663,21 +1652,8 @@ public final class Configuration implements Parcelable, Comparable<Configuration
        if (n != 0) return n;
        n = this.assetsSeq - that.assetsSeq;
        if (n != 0) return n;

        if (this.appBounds == null && that.appBounds != null) {
            return 1;
        } else if (this.appBounds != null && that.appBounds == null) {
            return -1;
        } else if (this.appBounds != null && that.appBounds != null) {
            n = this.appBounds.left - that.appBounds.left;
        n = windowConfiguration.compareTo(that.windowConfiguration);
        if (n != 0) return n;
            n = this.appBounds.top - that.appBounds.top;
            if (n != 0) return n;
            n = this.appBounds.right - that.appBounds.right;
            if (n != 0) return n;
            n = this.appBounds.bottom - that.appBounds.bottom;
            if (n != 0) return n;
        }

        // if (n != 0) return n;
        return n;
@@ -1765,33 +1741,6 @@ public final class Configuration implements Parcelable, Comparable<Configuration
        setLocales(loc == null ? LocaleList.getEmptyLocaleList() : new LocaleList(loc));
    }

    /**
     * @hide
     *
     * Helper method for setting the app bounds.
     */
    public void setAppBounds(Rect rect) {
        if (rect == null) {
            appBounds = null;
            return;
        }

        setAppBounds(rect.left, rect.top, rect.right, rect.bottom);
    }

    /**
     * @hide
     *
     * Helper method for setting the app bounds.
     */
    public void setAppBounds(int left, int top, int right, int bottom) {
        if (appBounds == null) {
            appBounds = new Rect();
        }

        appBounds.set(left, top, right, bottom);
    }

    /**
     * @hide
     *
@@ -2282,6 +2231,10 @@ public final class Configuration implements Parcelable, Comparable<Configuration
        if (base.assetsSeq != change.assetsSeq) {
            delta.assetsSeq = change.assetsSeq;
        }

        if (!base.windowConfiguration.equals(change.windowConfiguration)) {
            delta.windowConfiguration.setTo(change.windowConfiguration);
        }
        return delta;
    }

@@ -2354,10 +2307,9 @@ public final class Configuration implements Parcelable, Comparable<Configuration
                        SMALLEST_SCREEN_WIDTH_DP_UNDEFINED);
        configOut.densityDpi = XmlUtils.readIntAttribute(parser, XML_ATTR_DENSITY,
                DENSITY_DPI_UNDEFINED);
        configOut.appBounds =
            Rect.unflattenFromString(XmlUtils.readStringAttribute(parser, XML_ATTR_APP_BOUNDS));

        // For persistence, we don't care about assetsSeq, so do not read it out.
        // For persistence, we don't care about assetsSeq and WindowConfiguration, so do not read it
        // out.
    }


@@ -2427,11 +2379,7 @@ public final class Configuration implements Parcelable, Comparable<Configuration
            XmlUtils.writeIntAttribute(xml, XML_ATTR_DENSITY, config.densityDpi);
        }

        if (config.appBounds != null) {
            XmlUtils.writeStringAttribute(xml, XML_ATTR_APP_BOUNDS,
                config.appBounds.flattenToString());
        }

        // For persistence, we do not care about assetsSeq, so do not write it out.
        // For persistence, we do not care about assetsSeq and window configuration, so do not write
        // it out.
    }
}
+5 −4
Original line number Diff line number Diff line
@@ -23,6 +23,7 @@ import static android.view.DisplayInfoProto.LOGICAL_WIDTH;

import android.content.res.CompatibilityInfo;
import android.content.res.Configuration;
import android.graphics.Rect;
import android.os.Parcel;
import android.os.Parcelable;
import android.util.ArraySet;
@@ -568,10 +569,10 @@ public final class DisplayInfo implements Parcelable {
        outMetrics.xdpi = outMetrics.noncompatXdpi = physicalXDpi;
        outMetrics.ydpi = outMetrics.noncompatYdpi = physicalYDpi;

        width = configuration != null && configuration.appBounds != null
                ? configuration.appBounds.width() : width;
        height = configuration != null && configuration.appBounds != null
                ? configuration.appBounds.height() : height;
        final Rect appBounds = configuration != null
                ? configuration.windowConfiguration.getAppBounds() : null;
        width = appBounds != null ? appBounds.width() : width;
        height = appBounds != null ? appBounds.height() : height;

        outMetrics.noncompatWidthPixels  = outMetrics.widthPixels = width;
        outMetrics.noncompatHeightPixels = outMetrics.heightPixels = height;
Loading